about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorptitSeb <sebastien.chev@gmail.com>2021-07-13 15:45:36 +0200
committerptitSeb <sebastien.chev@gmail.com>2021-07-13 15:45:36 +0200
commit27d79eddec43654679594a935c21541eab3ec046 (patch)
tree17f94c44752d89e9fca3d9d09b32923ea39a4157 /src
parent0e5bc91a14beb8756f2f76d2827a67ba53159b2a (diff)
downloadbox64-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-xsrc/emu/x64emu.c5
-rwxr-xr-xsrc/emu/x64run.c9
-rwxr-xr-xsrc/emu/x64tls.c10
-rwxr-xr-xsrc/include/x64emu.h4
-rwxr-xr-xsrc/libtools/signals.c14
-rwxr-xr-xsrc/libtools/threads.c2
-rwxr-xr-xsrc/main.c2
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;