Fixed and improved handling of segments and Call Far and signal (helps Wine64)

This commit is contained in:
ptitSeb committed 2021-07-13 15:45:36 +02:00
1 parent 0e5bc91a14
commit 27d79eddec
7 files changed
+24 -22

No files matched your search

+3 -2
View File
@@ -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)
+6 -3
View File
@@ -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];
+4 -6
View File
@@ -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;
+2 -2
View File
@@ -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);
+7 -7
View File
@@ -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];
+1 -1
View File
@@ -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;
+1 -1
View File
@@ -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;