diff options
| author | ptitSeb <sebastien.chev@gmail.com> | 2021-07-13 15:45:36 +0200 |
|---|---|---|
| committer | ptitSeb <sebastien.chev@gmail.com> | 2021-07-13 15:45:36 +0200 |
| commit | 27d79eddec43654679594a935c21541eab3ec046 (patch) | |
| tree | 17f94c44752d89e9fca3d9d09b32923ea39a4157 /src | |
| parent | 0e5bc91a14beb8756f2f76d2827a67ba53159b2a (diff) | |
| download | box64-27d79eddec43654679594a935c21541eab3ec046.tar.gz box64-27d79eddec43654679594a935c21541eab3ec046.zip | |
Fixed and improved handling of segments and Call Far and signal (helps Wine64)
Diffstat (limited to 'src')
| -rwxr-xr-x | src/emu/x64emu.c | 5 | ||||
| -rwxr-xr-x | src/emu/x64run.c | 9 | ||||
| -rwxr-xr-x | src/emu/x64tls.c | 10 | ||||
| -rwxr-xr-x | src/include/x64emu.h | 4 | ||||
| -rwxr-xr-x | src/libtools/signals.c | 14 | ||||
| -rwxr-xr-x | src/libtools/threads.c | 2 | ||||
| -rwxr-xr-x | src/main.c | 2 |
7 files changed, 24 insertions, 22 deletions
diff --git a/src/emu/x64emu.c b/src/emu/x64emu.c index c5ef1b10..f65e6312 100755 --- a/src/emu/x64emu.c +++ b/src/emu/x64emu.c @@ -327,14 +327,15 @@ uint64_t GetRBP(x64emu_t *emu) { return R_RBP; } -void SetFS(x64emu_t *emu, uint16_t v) +/*void SetFS(x64emu_t *emu, uint16_t v) { emu->segs[_FS] = v; + emu->segs_serial[_FS] = 0; } uint16_t GetFS(x64emu_t *emu) { return emu->segs[_FS]; -} +}*/ void ResetFlags(x64emu_t *emu) diff --git a/src/emu/x64run.c b/src/emu/x64run.c index 2566009e..92a0dc11 100755 --- a/src/emu/x64run.c +++ b/src/emu/x64run.c @@ -499,7 +499,10 @@ x64emurun: case 0x8C: /* MOV Ed, Seg */ nextop = F8; GETED(0); - ED->dword[0] = emu->segs[((nextop&0x38)>>3)]; + if(MODREG) + ED->q[0] = emu->segs[((nextop&0x38)>>3)]; + else + ED->word[0] = emu->segs[((nextop&0x38)>>3)]; break; case 0x8D: /* LEA Gd,M */ nextop = F8; @@ -1061,7 +1064,7 @@ x64emurun: case 0xCF: /* IRET */ R_RIP = Pop(emu); - emu->segs[_CS] = Pop(emu); + emu->segs[_CS] = Pop(emu)&0xffff; emu->segs_serial[_CS] = 0; emu->eflags.x64 = ((Pop(emu) & 0x3F7FD7)/* & (0xffff-40)*/ ) | 0x2; // mask off res2 and res3 and on res1 RESET_FLAGS(emu); @@ -1431,7 +1434,7 @@ x64emurun: emu->error |= ERR_ILLEGAL; goto fini; } else { - Push16(emu, R_CS); + Push(emu, R_CS); Push(emu, R_RIP); R_RIP = ED->dword[0]; R_CS = (ED+1)->word[0]; diff --git a/src/emu/x64tls.c b/src/emu/x64tls.c index 59af88fb..7609fa58 100755 --- a/src/emu/x64tls.c +++ b/src/emu/x64tls.c @@ -142,12 +142,10 @@ int my_arch_prctl(x64emu_t *emu, int code, void* addr) *(void**)addr = GetSegmentBase(emu->segs[_GS]); return 0; case ARCH_SET_GS: - if(emu->segs[_GS]!=(0xa<<3)) { - pthread_once(&thread_key_once3, thread_key_alloc3); - emu->segs[_GS] = 0xa<<3; - if(!default_gs) - default_gs = 0xa<<3; - } + pthread_once(&thread_key_once3, thread_key_alloc3); + if(emu->segs[_GS]!=(0xa<<3)) + emu->segs[_GS] = 0xa<<3; // should not move! + emu->segs_serial[_GS] = 0; my_context->segtls[3].base = (uintptr_t)addr; my_context->segtls[3].limit = 0; my_context->segtls[3].present = 1; diff --git a/src/include/x64emu.h b/src/include/x64emu.h index 0a928afd..e7efbb07 100755 --- a/src/include/x64emu.h +++ b/src/include/x64emu.h @@ -34,8 +34,8 @@ void SetRSI(x64emu_t *emu, uint64_t v); void SetRBP(x64emu_t *emu, uint64_t v); void SetRSP(x64emu_t *emu, uint64_t v); void SetRIP(x64emu_t *emu, uint64_t v); -void SetFS(x64emu_t *emu, uint16_t v); -uint16_t GetFS(x64emu_t *emu); +//void SetFS(x64emu_t *emu, uint16_t v); +//uint16_t GetFS(x64emu_t *emu); uint64_t GetRSP(x64emu_t *emu); uint64_t GetRBP(x64emu_t *emu); void ResetFlags(x64emu_t *emu); diff --git a/src/libtools/signals.c b/src/libtools/signals.c index 69671859..26c13dff 100755 --- a/src/libtools/signals.c +++ b/src/libtools/signals.c @@ -444,13 +444,13 @@ void my_sigactionhandler_oldcode(int32_t sig, siginfo_t* info, void * ucntx, int uintptr_t restorer = my_context->restorer[sig]; // get that actual ESP first! x64emu_t *emu = thread_get_emu(); - uintptr_t *frame = (uintptr_t*)R_RSP; + uintptr_t frame = R_RSP; #if defined(DYNAREC) && defined(__aarch64__) ucontext_t *p = (ucontext_t *)ucntx; void * pc = (void*)p->uc_mcontext.pc; dynablock_t* db = (dynablock_t*)cur_db;//FindDynablockFromNativeAddress(pc); if(db) { - frame = (uintptr_t*)p->uc_mcontext.regs[10+_SP]; + frame = (uintptr_t)p->uc_mcontext.regs[10+_SP]; } #else (void)ucntx; (void)cur_db; @@ -460,9 +460,9 @@ void my_sigactionhandler_oldcode(int32_t sig, siginfo_t* info, void * ucntx, int int used_stack = 0; if(new_ss) { if(new_ss->ss_flags == SS_ONSTACK) { // already using it! - frame = (uintptr_t*)emu->regs[_SP].q[0]; + frame = (uintptr_t)emu->regs[_SP].q[0]; } else { - frame = (uintptr_t*)(((uintptr_t)new_ss->ss_sp + new_ss->ss_size - 16) & ~0x0f); + frame = (uintptr_t)(((uintptr_t)new_ss->ss_sp + new_ss->ss_size - 16) & ~0x0f); used_stack = 1; new_ss->ss_flags = SS_ONSTACK; } @@ -471,7 +471,7 @@ void my_sigactionhandler_oldcode(int32_t sig, siginfo_t* info, void * ucntx, int // TODO: do I need to really setup 2 stack frame? That doesn't seems right! // setup stack frame // try to fill some sigcontext.... - frame -= sizeof(x64_ucontext_t)/sizeof(uintptr_t); + frame -= sizeof(x64_ucontext_t); x64_ucontext_t *sigcontext = (x64_ucontext_t*)frame; // get general register sigcontext->uc_mcontext.gregs[X64_R8] = R_R8; @@ -488,9 +488,9 @@ void my_sigactionhandler_oldcode(int32_t sig, siginfo_t* info, void * ucntx, int sigcontext->uc_mcontext.gregs[X64_RDI] = R_RDI; sigcontext->uc_mcontext.gregs[X64_RSI] = R_RSI; sigcontext->uc_mcontext.gregs[X64_RBP] = R_RBP; - sigcontext->uc_mcontext.gregs[X64_RIP] = R_RIP; sigcontext->uc_mcontext.gregs[X64_RSP] = R_RSP; sigcontext->uc_mcontext.gregs[X64_RBX] = R_RBX; + sigcontext->uc_mcontext.gregs[X64_RIP] = emu->old_ip;//R_RIP; // old_ip is more accurate as the "current" IP // flags sigcontext->uc_mcontext.gregs[X64_EFL] = emu->eflags.x64; // get segments @@ -588,7 +588,7 @@ void my_sigactionhandler_oldcode(int32_t sig, siginfo_t* info, void * ucntx, int GO(RBP); #undef GO // set stack pointer - R_RSP = (uintptr_t)frame; + R_RSP = frame; // set frame pointer R_RBP = sigcontext->uc_mcontext.gregs[X64_RBP]; diff --git a/src/libtools/threads.c b/src/libtools/threads.c index 3dd10603..b56ebd9a 100755 --- a/src/libtools/threads.c +++ b/src/libtools/threads.c @@ -464,7 +464,7 @@ void* my_prepare_thread(x64emu_t *emu, void* f, void* arg, int ssize, void** pet emuthread_t *et = (emuthread_t*)calloc(1, sizeof(emuthread_t)); x64emu_t *emuthread = NewX64Emu(emu->context, (uintptr_t)f, (uintptr_t)stack, stacksize, 1); SetupX64Emu(emuthread); - SetFS(emuthread, GetFS(emu)); + //SetFS(emuthread, GetFS(emu)); et->emu = emuthread; et->fnc = (uintptr_t)f; et->arg = arg; diff --git a/src/main.c b/src/main.c index 0188fd1e..5f4e2cf8 100755 --- a/src/main.c +++ b/src/main.c @@ -66,7 +66,7 @@ int box64_novulkan = 0; char* libGL = NULL; uintptr_t fmod_smc_start = 0; uintptr_t fmod_smc_end = 0; -uint32_t default_gs = 0; +uint32_t default_gs = 0xa<<3; int jit_gdb = 0; int box64_tcmalloc_minimal = 0; |