about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorptitSeb <sebastien.chev@gmail.com>2025-06-13 13:44:05 +0200
committerptitSeb <sebastien.chev@gmail.com>2025-06-13 13:44:05 +0200
commit2d740c91d23f8d9d317c0bfad38abbf74fc41f7d (patch)
tree9965054eed1e95c4e40171f484cd2b57e43e9951 /src
parent926a59803d53c4e7d8ba3266c7b8ffd4aef3465d (diff)
downloadbox64-2d740c91d23f8d9d317c0bfad38abbf74fc41f7d.tar.gz
box64-2d740c91d23f8d9d317c0bfad38abbf74fc41f7d.zip
[DYNACACHE] More preparation work for internal relocations
Diffstat (limited to 'src')
-rw-r--r--src/dynarec/arm64/dynarec_arm64_00.c4
-rw-r--r--src/dynarec/arm64/dynarec_arm64_helper.c3
-rw-r--r--src/tools/bridge.c37
3 files changed, 40 insertions, 4 deletions
diff --git a/src/dynarec/arm64/dynarec_arm64_00.c b/src/dynarec/arm64/dynarec_arm64_00.c
index c78e4f74..443d497d 100644
--- a/src/dynarec/arm64/dynarec_arm64_00.c
+++ b/src/dynarec/arm64/dynarec_arm64_00.c
@@ -2602,7 +2602,7 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                         x87_purgecache(dyn, ninst, 0, x3, x1, x4);
                     if ((BOX64ENV(log)<2 && !BOX64ENV(rolling_log) && !BOX64ENV(dynarec_test)) && tmp) {
                         //GETIP(ip+3+8+8); // read the 0xCC
-                        call_n(dyn, ninst, *(void**)(addr+8), tmp);
+                        call_n(dyn, ninst, (void*)(addr+8), tmp);
                         addr+=8+8;
                     } else {
                         GETIP(ip+1); // read the 0xCC
@@ -3395,7 +3395,7 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                         x87_purgecache(dyn, ninst, 0, x3, x1, x4);
                     if ((BOX64ENV(log)<2 && !BOX64ENV(rolling_log)) && dyn->insts[ninst].natcall && tmp) {
                         //GETIP(ip+3+8+8); // read the 0xCC
-                        call_n(dyn, ninst, *(void**)(dyn->insts[ninst].natcall+2+8), tmp);
+                        call_n(dyn, ninst, (void*)(dyn->insts[ninst].natcall+2+8), tmp);
                         SMWRITE2();
                         POP1(xRIP);   // pop the return address
                         dyn->last_ip = addr;
diff --git a/src/dynarec/arm64/dynarec_arm64_helper.c b/src/dynarec/arm64/dynarec_arm64_helper.c
index 12274e44..092452d2 100644
--- a/src/dynarec/arm64/dynarec_arm64_helper.c
+++ b/src/dynarec/arm64/dynarec_arm64_helper.c
@@ -879,7 +879,8 @@ void call_n(dynarec_arm_t* dyn, int ninst, void* fnc, int w)
     MOVx_REG(x4, xR8);
     MOVx_REG(x5, xR9);
     // native call
-    TABLE64(16, (uintptr_t)fnc);    // using x16 as scratch regs for call address
+    // fnc is indirect, to help with relocation (but PltResolver might be an issue here)
+    TABLE64(16, *(uintptr_t*)fnc);    // using x16 as scratch regs for call address
     BLR(16);
     // put return value in x64 regs
     if(w>0) {
diff --git a/src/tools/bridge.c b/src/tools/bridge.c
index e9669fa2..60b6024a 100644
--- a/src/tools/bridge.c
+++ b/src/tools/bridge.c
@@ -21,6 +21,9 @@
 #ifdef DYNAREC
 #include "dynablock.h"
 #endif
+#ifdef BOX32
+#include "box32context.h"
+#endif
 
 KHASH_MAP_INIT_INT64(bridgemap, uintptr_t)
 
@@ -258,10 +261,42 @@ void fini_bridge_helper()
     cleanAlternate();
 }
 
+#ifdef BOX32
+int isNativeCall32(uintptr_t addr, uintptr_t* calladdress, uint16_t* retn)
+{
+#define PK(a)       *(uint8_t*)(addr+a)
+#define PK32(a)     *(uint32_t*)(addr+a)
+
+    if(!addr || !getProtection(addr))
+        return 0;
+    if(PK(0)==0xff && PK(1)==0x25) {  // absolute jump, maybe the GOT
+        ptr_t a1 = (PK32(2));   // need to add a check to see if the address is from the GOT !
+        addr = (uintptr_t)getAlternate(from_ptrv(a1)); 
+    }
+    if(addr<0x10000 || !getProtection(addr))    // too low, that is suspicious
+        return 0;
+    onebridge_t *b = (onebridge_t*)(addr);
+    if(b->CC==0xCC && b->S=='S' && b->C=='C' && b->w!=(wrapper_t)0 && b->f!=(uintptr_t)PltResolver32) {
+        // found !
+        if(retn) *retn = (b->C3==0xC2)?b->N:0;
+        if(calladdress) *calladdress = addr+1;
+        return 1;
+    }
+    return 0;
+#undef PK32
+#undef PK
+}
+#else
+int isNativeCall32(uintptr_t addr, uintptr_t* calladdress, int* retn)
+{
+    return 0;
+}
+#endif
+
 int isNativeCallInternal(uintptr_t addr, int is32bits, uintptr_t* calladdress, uint16_t* retn)
 {
     if (is32bits)
-        addr &= 0xFFFFFFFFLL;
+        return isNativeCall32(addr, calladdress, retn);
 
 #define PK(a)   *(uint8_t*)(addr + a)
 #define PK32(a) *(int32_t*)(addr + a)