about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorptitSeb <sebastien.chev@gmail.com>2021-09-02 20:25:58 +0200
committerptitSeb <sebastien.chev@gmail.com>2021-09-02 20:25:58 +0200
commit5d5ef75337cd4db7224d5e0cdb6da2dc96ab8224 (patch)
tree6b6f013c09789da472917ff5e00f6bf0d2f7899b /src
parentc3ef6380a7baa6457974fe2eca1652dff6808cca (diff)
downloadbox64-5d5ef75337cd4db7224d5e0cdb6da2dc96ab8224.tar.gz
box64-5d5ef75337cd4db7224d5e0cdb6da2dc96ab8224.zip
Add some support vor VSyscall
Diffstat (limited to 'src')
-rwxr-xr-xsrc/box64context.c11
-rwxr-xr-xsrc/emu/x64syscall.c4
-rwxr-xr-xsrc/include/box64context.h1
-rwxr-xr-xsrc/include/bridge.h2
-rwxr-xr-xsrc/tools/bridge.c44
-rwxr-xr-xsrc/tools/bridge_private.h6
6 files changed, 67 insertions, 1 deletions
diff --git a/src/box64context.c b/src/box64context.c
index 5dc64825..eb2512b3 100755
--- a/src/box64context.c
+++ b/src/box64context.c
@@ -163,7 +163,16 @@ box64context_t *NewBox64Context(int argc)
     context->versym = NewDictionnary();
     context->system = NewBridge();
     // create vsyscall
-    context->vsyscall = AddBridge(context->system, vFv, x64Syscall, 0, NULL);
+    context->vsyscall = AddBridge(context->system, vFEv, x64Syscall, 0, NULL);
+    // create the vsyscalls
+    context->vsyscalls[0] = AddVSyscall(context->system, 96);
+    context->vsyscalls[1] = AddVSyscall(context->system, 201);
+    context->vsyscalls[2] = AddVSyscall(context->system, 309);
+    // create the alternate to map at address
+    addAlternate((void*)context->vsyscalls[0], (void*)0xffffffffff600000);
+    addAlternate((void*)context->vsyscalls[1], (void*)0xffffffffff600400);
+    addAlternate((void*)context->vsyscalls[2], (void*)0xffffffffff600800);
+    // get handle to box64 itself
     context->box64lib = dlopen(NULL, RTLD_NOW|RTLD_GLOBAL);
     context->dlprivate = NewDLPrivate();
 
diff --git a/src/emu/x64syscall.c b/src/emu/x64syscall.c
index 18689c90..ccdbadd4 100755
--- a/src/emu/x64syscall.c
+++ b/src/emu/x64syscall.c
@@ -158,10 +158,14 @@ scwrap_t syscallwrap[] = {
     { 274, __NR_get_robust_list, 3},
     { 294, __NR_inotify_init1, 1},
     { 298, __NR_perf_event_open, 5},
+    { 309, __NR_getcpu, 3}, // need wrapping?
     { 315, __NR_sched_getattr, 4},
     { 318, __NR_getrandom, 3},
     { 319, __NR_memfd_create, 2},
+    #ifdef __NR_statx
+    // TODO: implement fallback if __NR_statx is not defined
     { 332, __NR_statx, 4},
+    #endif
     #ifdef __NR_fchmodat4
     { 434, __NR_fchmodat4, 4},
     #endif
diff --git a/src/include/box64context.h b/src/include/box64context.h
index 1fe43d84..694accb3 100755
--- a/src/include/box64context.h
+++ b/src/include/box64context.h
@@ -104,6 +104,7 @@ typedef struct box64context_s {
     kh_threadstack_t    *stacksizes;    // stack sizes attributes for thread (temporary)
     bridge_t            *system;        // other bridges
     uintptr_t           vsyscall;       // vsyscall bridge value
+    uintptr_t           vsyscalls[3];   // the 3 x86 VSyscall pseudo bridges (mapped at 0xffffffffff600000+)
     dlprivate_t         *dlprivate;     // dlopen library map
     kh_symbolmap_t      *glwrappers;    // the map of wrapper for glProcs (for GLX or SDL1/2)
     kh_symbolmap_t      *glmymap;       // link to the mysymbolmap of libGL
diff --git a/src/include/bridge.h b/src/include/bridge.h
index 9499b440..9859ae85 100755
--- a/src/include/bridge.h
+++ b/src/include/bridge.h
@@ -17,6 +17,8 @@ uintptr_t AddAutomaticBridge(x64emu_t* emu, bridge_t* bridge, wrapper_t w, void*
 void* GetNativeFnc(uintptr_t fnc);
 void* GetNativeFncOrFnc(uintptr_t fnc);
 
+uintptr_t AddVSyscall(bridge_t* bridge, int num);
+
 int hasAlternate(void* addr);
 void* getAlternate(void* addr);
 void addAlternate(void* addr, void* alt);
diff --git a/src/tools/bridge.c b/src/tools/bridge.c
index 3fdaa2ac..5f6bb5af 100755
--- a/src/tools/bridge.c
+++ b/src/tools/bridge.c
@@ -203,6 +203,50 @@ void* GetNativeFncOrFnc(uintptr_t fnc)
     return (void*)b->f;
 }
 
+// using the brdige mecanism for the VSyscall
+uintptr_t AddVSyscall(bridge_t* bridge, int num)
+{
+    brick_t *b = NULL;
+    int sz = -1;
+    #ifdef DYNAREC
+    int prot = 0;
+    do {
+        #endif
+        pthread_mutex_lock(&my_context->mutex_bridge);
+        b = bridge->last;
+        if(b->sz == NBRICK) {
+            b->next = NewBrick();
+            b = b->next;
+            bridge->last = b;
+        }
+	    sz = b->sz;
+        #ifdef DYNAREC
+        pthread_mutex_unlock(&my_context->mutex_bridge);
+        if(box64_dynarec) {
+            prot=(getProtection((uintptr_t)b->b)&PROT_DYNAREC)?1:0;
+            if(prot)
+                unprotectDB((uintptr_t)b->b, NBRICK*sizeof(onebridge_t));
+            else    // only add DB if there is no protection
+                addDBFromAddressRange((uintptr_t)&b->b[b->sz].CC, sizeof(onebridge_t));
+        }
+    } while(sz!=b->sz); // this while loop if someone took the slot when the bridge mutex was unlocked doing memory protection managment
+    pthread_mutex_lock(&my_context->mutex_bridge);
+    #endif
+    b->sz++;
+    b->b[sz].B8 = 0xB8;
+    b->b[sz].num = num;
+    b->b[sz]._0F = 0x0F;
+    b->b[sz]._05 = 0x05;
+    b->b[sz]._C3 = 0xC3;
+    pthread_mutex_unlock(&my_context->mutex_bridge);
+    #ifdef DYNAREC
+    if(box64_dynarec)
+        protectDB((uintptr_t)b->b, NBRICK*sizeof(onebridge_t));
+    #endif
+
+    return (uintptr_t)&b->b[sz].CC;
+}
+
 #ifdef HAVE_TRACE
 KHASH_MAP_INIT_INT64(bridgename, const char*)
 static kh_bridgename_t *bridgename;
diff --git a/src/tools/bridge_private.h b/src/tools/bridge_private.h
index 928e1e02..0983cea0 100755
--- a/src/tools/bridge_private.h
+++ b/src/tools/bridge_private.h
@@ -15,6 +15,12 @@ typedef union onebridge_s {
     uint8_t C3;     // C2 or C3 ret
     uint16_t N;     // N in case of C2 ret
     };
+    struct {
+    uint8_t B8;     // B8 00 11 22 33 mov rax, num
+    uint32_t num;
+    uint8_t _0F; uint8_t _05;   // 0F 05 syscall
+    uint8_t _C3;    // C3 ret
+    };
     uint64_t dummy[4];
 } onebridge_t;
 #pragma pack(pop)