about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorptitSeb <sebastien.chev@gmail.com>2021-03-06 17:54:47 +0100
committerptitSeb <sebastien.chev@gmail.com>2021-03-06 17:54:47 +0100
commit8b456d5a60536fb94108f504602feaaec9fc71c1 (patch)
tree32a03219266631f44fbc9ec677022cbebdbf2831 /src
parent1b350d24c30657c8ea8afd4f3aeeda960a0a2357 (diff)
downloadbox64-8b456d5a60536fb94108f504602feaaec9fc71c1.tar.gz
box64-8b456d5a60536fb94108f504602feaaec9fc71c1.zip
Some work on TLS (not sure it's a good idea to separate 64 FS: prefix there)
Diffstat (limited to 'src')
-rwxr-xr-xsrc/box64context.c4
-rw-r--r--src/emu/modrm.h18
-rwxr-xr-xsrc/emu/x64emu.c4
-rwxr-xr-xsrc/emu/x64run.c8
-rw-r--r--src/emu/x64run64.c96
-rwxr-xr-xsrc/emu/x64run_private.c48
-rwxr-xr-xsrc/emu/x64run_private.h4
-rwxr-xr-xsrc/emu/x64tls.c18
-rwxr-xr-xsrc/include/box64context.h2
-rwxr-xr-xsrc/include/debug.h2
-rwxr-xr-xsrc/main.c2
11 files changed, 182 insertions, 24 deletions
diff --git a/src/box64context.c b/src/box64context.c
index 4c75e98e..75fb5028 100755
--- a/src/box64context.c
+++ b/src/box64context.c
@@ -107,9 +107,9 @@ box64context_t *NewBox64Context(int argc)
     pthread_key_create(&context->tlskey, free_tlsdatasize);
 
 
-    for (int i=0; i<4; ++i) context->canary[i] = 1 +  getrand(255);
+    for (int i=0; i<8; ++i) context->canary[i] = 1 +  getrand(255);
     context->canary[getrand(4)] = 0;
-    printf_log(LOG_DEBUG, "Setting up canary (for Stack protector) at GS:0x14, value:%08X\n", *(uint32_t*)context->canary);
+    printf_log(LOG_DEBUG, "Setting up canary (for Stack protector) at FS:0x14, value:%08X\n", *(uint32_t*)context->canary);
 
     initAllHelpers(context);
 
diff --git a/src/emu/modrm.h b/src/emu/modrm.h
index af678823..9152dd05 100644
--- a/src/emu/modrm.h
+++ b/src/emu/modrm.h
@@ -13,14 +13,16 @@
 #define STEP

 #endif

 

-#define GETED(D)    oped=GetEd(emu, rex, nextop, D)

-#define GETGD       opgd=GetGd(emu, rex, nextop)

-#define GETEB(D)    oped=GetEb(emu, rex, nextop, D)

-#define GETGB       opgd=GetGb(emu, rex, nextop)

-#define GETEW(D)    oped=GetEw(emu, rex, nextop, D)

-#define GETGW       opgd=GetGw(emu, rex, nextop)

-#define GETEX(D)    opex=GetEx(emu, rex, nextop, D)

-#define GETGX       opgx=GetGx(emu, rex, nextop)

+#define GETED(D)            oped=GetEd(emu, rex, nextop, D)

+#define GETED_OFFS(D, O)    oped=GetEdO(emu, rex, nextop, D, O)

+#define GETGD               opgd=GetGd(emu, rex, nextop)

+#define GETEB(D)            oped=GetEb(emu, rex, nextop, D)

+#define GETEB_OFFS(D, O)    oped=GetEbO(emu, rex, nextop, D, O)

+#define GETGB               opgd=GetGb(emu, rex, nextop)

+#define GETEW(D)            oped=GetEw(emu, rex, nextop, D)

+#define GETGW               opgd=GetGw(emu, rex, nextop)

+#define GETEX(D)            opex=GetEx(emu, rex, nextop, D)

+#define GETGX               opgx=GetGx(emu, rex, nextop)

 #define ED  oped

 #define GD  opgd

 #define EB  oped

diff --git a/src/emu/x64emu.c b/src/emu/x64emu.c
index 64489f00..80752a0a 100755
--- a/src/emu/x64emu.c
+++ b/src/emu/x64emu.c
@@ -73,8 +73,8 @@ static void internalX64Setup(x64emu_t* emu, box64context_t *context, uintptr_t s
     // fake init of segments...
     emu->segs[_CS] = 0x73;
     emu->segs[_DS] = emu->segs[_ES] = emu->segs[_SS] = 0x7b;
-    emu->segs[_FS] = default_fs;
-    emu->segs[_GS] = 0x33;
+    emu->segs[_FS] = 0x33;
+    emu->segs[_GS] = default_gs;
     // setup fpu regs
     reset_fpu(emu);
 }
diff --git a/src/emu/x64run.c b/src/emu/x64run.c
index ece834c0..77c6db62 100755
--- a/src/emu/x64run.c
+++ b/src/emu/x64run.c
@@ -237,6 +237,14 @@ x64emurun:
                 else
                     GD->sdword[0] = ED->sdword[0];  // meh?
             break;
+        case 0x64:                      /* FS: prefix */
+            if(Run64(emu, rex)) {
+                unimp = 1;
+                goto fini;
+            }
+            if(emu->quit)
+                goto fini;
+            break;
 
         case 0x66:                      /* 16bits prefix */
             if(Run66(emu, rex)) {
diff --git a/src/emu/x64run64.c b/src/emu/x64run64.c
new file mode 100644
index 00000000..92db3f52
--- /dev/null
+++ b/src/emu/x64run64.c
@@ -0,0 +1,96 @@
+#define _GNU_SOURCE

+#include <stdint.h>

+#include <stdio.h>

+#include <stdlib.h>

+#include <math.h>

+#include <string.h>

+#include <signal.h>

+#include <sys/types.h>

+#include <unistd.h>

+

+#include "debug.h"

+#include "box64stack.h"

+#include "x64emu.h"

+#include "x64run.h"

+#include "x64emu_private.h"

+#include "x64run_private.h"

+#include "x64primop.h"

+#include "x64trace.h"

+#include "x87emu_private.h"

+#include "box64context.h"

+#include "bridge.h"

+//#include "signals.h"

+#ifdef DYNAREC

+#include "../dynarec/arm_lock_helper.h"

+#endif

+

+#include "modrm.h"

+

+int Run64(x64emu_t *emu, rex_t rex)

+{

+    uint8_t opcode;

+    uint8_t nextop;

+    uint8_t tmp8u;

+    int16_t tmp16s;

+    uint16_t tmp16u;

+    reg64_t *oped, *opgd;

+    uintptr_t tlsdata = GetFSBaseEmu(emu);

+

+    opcode = F8;

+    // REX prefix before the F0 are ignored

+    rex.rex = 0;

+    while(opcode>=0x40 && opcode<=0x4f) {

+        rex.rex = opcode;

+        opcode = F8;

+    }

+

+    switch(opcode) {

+

+        case 0x88:                      /* MOV Eb,Gb */

+            nextop = F8;

+            GETEB_OFFS(0, tlsdata);

+            GETGB;

+            EB->byte[0] = GB;

+            break;

+        case 0x89:                    /* MOV Ed,Gd */

+            nextop = F8;

+            GETED_OFFS(0, tlsdata);

+            GETGD;

+            if(rex.w) {

+                ED->q[0] = GD->q[0];

+            } else {

+                //if ED is a reg, than the opcode works like movzx

+                if(MODREG)

+                    ED->q[0] = GD->dword[0];

+                else

+                    ED->dword[0] = GD->dword[0];

+            }

+            break;

+

+        case 0x8B:                      /* MOV Gd,Ed */

+            nextop = F8;

+            GETED_OFFS(0, tlsdata);

+            GETGD;

+            if(rex.w)

+                GD->q[0] = ED->q[0];

+            else

+                GD->q[0] = ED->dword[0];

+            break;

+

+        case 0xC7:                      /* MOV Ed,Id */

+            nextop = F8;

+            GETED_OFFS(4, tlsdata);

+            if(rex.w)

+                ED->q[0] = F32S64;

+            else

+                if(MODREG)

+                    ED->q[0] = F32;

+                else

+                    ED->dword[0] = F32;

+            break;

+

+       default:

+            return 1;

+    }

+    return 0;

+}
\ No newline at end of file
diff --git a/src/emu/x64run_private.c b/src/emu/x64run_private.c
index 928d531f..a6b900fb 100755
--- a/src/emu/x64run_private.c
+++ b/src/emu/x64run_private.c
@@ -1021,6 +1021,32 @@ reg64_t* GetECommon(x64emu_t* emu, rex_t rex, uint8_t m, uint8_t delta)
     }
 }
 
+reg64_t* GetECommonO(x64emu_t* emu, rex_t rex, uint8_t m, uint8_t delta, uintptr_t base)
+{
+    if (m<=7) {
+        if(m==0x4) {
+            uint8_t sib = Fetch8(emu);
+            base += ((sib&0x7)==5)?((uint64_t)(int64_t)Fetch32s(emu)):(emu->regs[(sib&0x7)+(rex.b<<3)].q[0]); // base
+            base += (emu->sbiidx[((sib>>3)&7)+(rex.x<<3)]->sq[0] << (sib>>6));
+            return (reg64_t*)base;
+        } else if (m==0x5) { //disp32
+            base += Fetch32s(emu);
+            return (reg64_t*)(base+R_RIP+delta);
+        }
+        return (reg64_t*)(emu->regs[m+(rex.b<<3)].q[0]);
+    } else {
+        if((m&7)==4) {
+            uint8_t sib = Fetch8(emu);
+            base += emu->regs[(sib&0x7)+(rex.b<<3)].q[0]; // base
+            base += (emu->sbiidx[((sib>>3)&7)+(rex.x<<3)]->sq[0] << (sib>>6));
+        } else {
+            base += emu->regs[(m&0x7)+(rex.b<<3)].q[0];
+        }
+        base+=(m&0x80)?Fetch32s(emu):Fetch8s(emu);
+        return (reg64_t*)base;
+    }
+}
+
 reg64_t* GetEb(x64emu_t *emu, rex_t rex, uint8_t v, uint8_t delta)
 {
     // rex ignored here
@@ -1035,6 +1061,20 @@ reg64_t* GetEb(x64emu_t *emu, rex_t rex, uint8_t v, uint8_t delta)
     } else return GetECommon(emu, rex, m, delta);
 }
 
+reg64_t* GetEbO(x64emu_t *emu, rex_t rex, uint8_t v, uint8_t delta, uintptr_t offset)
+{
+    // rex ignored here
+    uint8_t m = v&0xC7;    // filter Eb
+    if(m>=0xC0) {
+        if(rex.rex) {
+            return &emu->regs[(m&0x07)+(rex.b<<3)];
+        } else {
+            int lowhigh = (m&4)>>2;
+            return (reg64_t *)(((char*)(&emu->regs[(m&0x03)]))+lowhigh);  //?
+        }
+    } else return GetECommonO(emu, rex, m, delta, offset);
+}
+
 reg64_t* GetEd(x64emu_t *emu, rex_t rex, uint8_t v, uint8_t delta)
 {
     uint8_t m = v&0xC7;    // filter Ed
@@ -1043,6 +1083,14 @@ reg64_t* GetEd(x64emu_t *emu, rex_t rex, uint8_t v, uint8_t delta)
     } else return GetECommon(emu, rex, m, delta);
 }
 
+reg64_t* GetEdO(x64emu_t *emu, rex_t rex, uint8_t v, uint8_t delta, uintptr_t offset)
+{
+    uint8_t m = v&0xC7;    // filter Ed
+    if(m>=0xC0) {
+         return &emu->regs[(m&0x07)+(rex.b<<3)];
+    } else return GetECommonO(emu, rex, m, delta, offset);
+}
+
 #define GetEw GetEd
 
 reg64_t* GetEw16(x64emu_t *emu, rex_t rex, uint8_t v)
diff --git a/src/emu/x64run_private.h b/src/emu/x64run_private.h
index c2161b3f..b7c7ee5f 100755
--- a/src/emu/x64run_private.h
+++ b/src/emu/x64run_private.h
@@ -74,8 +74,11 @@ static inline void Push(x64emu_t *emu, uint64_t v)
 // the op code definition can be found here: http://ref.x86asm.net/geek32.html
 
 reg64_t* GetECommon(x64emu_t* emu, rex_t rex, uint8_t m, uint8_t delta);
+reg64_t* GetECommonO(x64emu_t* emu, rex_t rex, uint8_t m, uint8_t delta, uintptr_t offset);
 reg64_t* GetEb(x64emu_t *emu, rex_t rex, uint8_t v, uint8_t delta);
+reg64_t* GetEbO(x64emu_t *emu, rex_t rex, uint8_t v, uint8_t delta, uintptr_t offset);
 reg64_t* GetEd(x64emu_t *emu, rex_t rex, uint8_t v, uint8_t delta);
+reg64_t* GetEdO(x64emu_t *emu, rex_t rex, uint8_t v, uint8_t delta, uintptr_t offset);
 #define GetEw GetEd
 reg64_t* GetEw16(x64emu_t *emu, rex_t rex, uint8_t v);
 reg64_t* GetEw16off(x64emu_t *emu, rex_t rex, uint8_t v, uintptr_t offset);
@@ -93,6 +96,7 @@ void UpdateFlags(x64emu_t *emu);
 #define RESET_FLAGS(emu) emu->df = d_none
 
 int Run0F(x64emu_t *emu, rex_t rex);
+int Run64(x64emu_t *emu, rex_t rex);
 int Run66(x64emu_t *emu, rex_t rex);
 int Run660F(x64emu_t *emu, rex_t rex);
 //int Run67(x64emu_t *emu, rex_t rex);
diff --git a/src/emu/x64tls.c b/src/emu/x64tls.c
index b76646b5..2396eee6 100755
--- a/src/emu/x64tls.c
+++ b/src/emu/x64tls.c
@@ -133,8 +133,8 @@ uint32_t my_modify_ldt(x64emu_t* emu, int op, thread_area_t* td, int size)
 static tlsdatasize_t* setupTLSData(box64context_t* context)
 {
     // Setup the GS segment:
-    int dtsize = context->elfsize*8;
-    void *ptr = (char*)malloc(context->tlssize+4+POS_TLS+dtsize);
+    int dtsize = context->elfsize*16;
+    void *ptr = (char*)malloc(context->tlssize+8+POS_TLS+dtsize);
     memcpy(ptr, context->tlsdata, context->tlssize);
     tlsdatasize_t *data = (tlsdatasize_t*)calloc(1, sizeof(tlsdatasize_t));
     data->tlsdata = ptr;
@@ -142,20 +142,20 @@ static tlsdatasize_t* setupTLSData(box64context_t* context)
     pthread_setspecific(context->tlskey, data);
     // copy canary...
     memset((void*)((uintptr_t)ptr+context->tlssize), 0, POS_TLS+dtsize);            // set to 0 remining bytes
-    memcpy((void*)((uintptr_t)ptr+context->tlssize+0x14), context->canary, 4);      // put canary in place
+    memcpy((void*)((uintptr_t)ptr+context->tlssize+0x14), context->canary, sizeof(void*));      // put canary in place
     uintptr_t tlsptr = (uintptr_t)ptr+context->tlssize;
-    memcpy((void*)((uintptr_t)ptr+context->tlssize+0x0), &tlsptr, 4);
+    memcpy((void*)((uintptr_t)ptr+context->tlssize+0x0), &tlsptr, sizeof(void*));
     uintptr_t dtp = (uintptr_t)ptr+context->tlssize+POS_TLS;
-    memcpy((void*)(tlsptr+0x4), &dtp, 4);
+    memcpy((void*)(tlsptr+sizeof(void*)), &dtp, sizeof(void*));
     if(dtsize) {
-        for (int i=0; i<context->elfsize; ++i) {
+        for (size_t i=0; i<context->elfsize; ++i) {
             // set pointer
             dtp = (uintptr_t)ptr + (context->tlssize + GetTLSBase(context->elfs[i]));
-            memcpy((void*)((uintptr_t)ptr+context->tlssize+POS_TLS+i*8), &dtp, 4);
-            memcpy((void*)((uintptr_t)ptr+context->tlssize+POS_TLS+i*8+4), &i, 4); // index
+            memcpy((void*)((uintptr_t)ptr+context->tlssize+POS_TLS+i*16), &dtp, sizeof(void*));
+            memcpy((void*)((uintptr_t)ptr+context->tlssize+POS_TLS+i*16+8), &i, sizeof(void*)); // index
         }
     }
-    memcpy((void*)((uintptr_t)ptr+context->tlssize+0x10), &context->vsyscall, 4);  // address of vsyscall
+    memcpy((void*)((uintptr_t)ptr+context->tlssize+0x10), &context->vsyscall, sizeof(void*));  // address of vsyscall
     return data;
 }
 
diff --git a/src/include/box64context.h b/src/include/box64context.h
index ed8cd118..6e4d9052 100755
--- a/src/include/box64context.h
+++ b/src/include/box64context.h
@@ -169,7 +169,7 @@ typedef struct box64context_s {
     int                 atfork_sz;
     int                 atfork_cap;
 
-    uint8_t             canary[4];
+    uint8_t             canary[8];
 
     uintptr_t           signals[MAX_SIGNAL];
     uintptr_t           restorer[MAX_SIGNAL];
diff --git a/src/include/debug.h b/src/include/debug.h
index 8b440787..873db669 100755
--- a/src/include/debug.h
+++ b/src/include/debug.h
@@ -18,7 +18,7 @@ extern int box64_novulkan;  // disabling the use of wrapped vulkan
 extern uintptr_t   trace_start, trace_end;
 extern char* trace_func;
 extern uintptr_t fmod_smc_start, fmod_smc_end; // to handle libfmod (from Unreal) SMC (self modifying code)
-extern uint32_t default_fs;
+extern uint32_t default_gs;
 extern int jit_gdb; // launch gdb when a segfault is trapped
 extern int box64_tcmalloc_minimal;  // when using tcmalloc_minimal
 #define LOG_NONE 0
diff --git a/src/main.c b/src/main.c
index d6da7513..2abfc604 100755
--- a/src/main.c
+++ b/src/main.c
@@ -53,7 +53,7 @@ uintptr_t   trace_start = 0, trace_end = 0;
 char* trace_func = NULL;
 uintptr_t fmod_smc_start = 0;
 uintptr_t fmod_smc_end = 0;
-uint32_t default_fs = 0;
+uint32_t default_gs = 0;
 int jit_gdb = 0;
 int box64_tcmalloc_minimal = 0;