about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorptitSeb <sebastien.chev@gmail.com>2024-09-16 16:10:29 +0200
committerptitSeb <sebastien.chev@gmail.com>2024-09-16 16:10:29 +0200
commit446d57122c78a4f475380686f21e7dc6cb298396 (patch)
tree84b907d69967696584925182caf8fb58dba7fc8d /src
parent1e8807ac0a21c6eaf53d30229d94fb8fd3533f6b (diff)
downloadbox64-446d57122c78a4f475380686f21e7dc6cb298396.tar.gz
box64-446d57122c78a4f475380686f21e7dc6cb298396.zip
[DYNAREC] Make sure jump address is wrapped on 32bits address space
Diffstat (limited to 'src')
-rw-r--r--src/dynarec/arm64/dynarec_arm64_00.c8
-rw-r--r--src/dynarec/arm64/dynarec_arm64_0f.c8
-rw-r--r--src/dynarec/arm64/dynarec_arm64_helper.c3
-rw-r--r--src/dynarec/dynarec_native_functions.c4
-rw-r--r--src/dynarec/dynarec_native_functions.h2
-rw-r--r--src/dynarec/la64/dynarec_la64_00.c16
-rw-r--r--src/dynarec/la64/dynarec_la64_0f.c8
-rw-r--r--src/dynarec/rv64/dynarec_rv64_00_3.c16
-rw-r--r--src/dynarec/rv64/dynarec_rv64_helper.c3
9 files changed, 52 insertions, 16 deletions
diff --git a/src/dynarec/arm64/dynarec_arm64_00.c b/src/dynarec/arm64/dynarec_arm64_00.c
index 1b271896..a8db155b 100644
--- a/src/dynarec/arm64/dynarec_arm64_00.c
+++ b/src/dynarec/arm64/dynarec_arm64_00.c
@@ -3050,7 +3050,7 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                 #endif
             }
             #if STEP < 2
-            if(!rex.is32bits && isNativeCall(dyn, addr+i32, &dyn->insts[ninst].natcall, &dyn->insts[ninst].retn))
+            if(!rex.is32bits && isNativeCall(dyn, addr+i32, rex.is32bits, &dyn->insts[ninst].natcall, &dyn->insts[ninst].retn))
                 tmp = dyn->insts[ninst].pass2choice = 3;
             else
                 tmp = dyn->insts[ninst].pass2choice = 0;
@@ -3144,7 +3144,11 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                         *ok = 0;
                         *need_epilog = 0;
                     }
-                    jump_to_next(dyn, addr+i32, 0, ninst, rex.is32bits);
+                    if(rex.is32bits)
+                        j64 = (uint32_t)(addr+i32);
+                    else
+                        j64 = addr+i32;
+                    jump_to_next(dyn, j64, 0, ninst, rex.is32bits);
                     break;
             }
             break;
diff --git a/src/dynarec/arm64/dynarec_arm64_0f.c b/src/dynarec/arm64/dynarec_arm64_0f.c
index 1c288c2c..38a705b5 100644
--- a/src/dynarec/arm64/dynarec_arm64_0f.c
+++ b/src/dynarec/arm64/dynarec_arm64_0f.c
@@ -1549,8 +1549,12 @@ uintptr_t dynarec64_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
         #define GO(GETFLAGS, NO, YES, F)   \

             READFLAGS(F);                                               \

             i32_ = F32S;                                                \

+            if(rex.is32bits)                                            \

+                j64 = (uint32_t)(addr+i32_);                            \

+            else                                                        \

+                j64 = addr+i32_;                                        \

             BARRIER(BARRIER_MAYBE);                                     \

-            JUMP(addr+i32_, 1);                                         \

+            JUMP(j64, 1);                                               \

             GETFLAGS;                                                   \

             if(dyn->insts[ninst].x64.jmp_insts==-1 ||                   \

                 CHECK_CACHE()) {                                        \

@@ -1560,7 +1564,7 @@ uintptr_t dynarec64_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                 if(dyn->insts[ninst].x64.jmp_insts==-1) {               \

                     if(!(dyn->insts[ninst].x64.barrier&BARRIER_FLOAT))  \

                         fpu_purgecache(dyn, ninst, 1, x1, x2, x3);      \

-                    jump_to_next(dyn, addr+i32_, 0, ninst, rex.is32bits); \

+                    jump_to_next(dyn, j64, 0, ninst, rex.is32bits);     \

                 } else {                                                \

                     CacheTransform(dyn, ninst, cacheupd, x1, x2, x3);   \

                     i32 = dyn->insts[dyn->insts[ninst].x64.jmp_insts].address-(dyn->native_size);    \

diff --git a/src/dynarec/arm64/dynarec_arm64_helper.c b/src/dynarec/arm64/dynarec_arm64_helper.c
index c332b40a..7f8c57cd 100644
--- a/src/dynarec/arm64/dynarec_arm64_helper.c
+++ b/src/dynarec/arm64/dynarec_arm64_helper.c
@@ -569,6 +569,9 @@ void jump_to_next(dynarec_arm_t* dyn, uintptr_t ip, int reg, int ninst, int is32
     MAYUSE(dyn); MAYUSE(ninst);
     MESSAGE(LOG_DUMP, "Jump to next\n");
 
+    if(is32bits)
+        ip &= 0xffffffffLL;
+
     SMEND();
     if(reg) {
         if(reg!=xRIP) {
diff --git a/src/dynarec/dynarec_native_functions.c b/src/dynarec/dynarec_native_functions.c
index c29e5083..5a086018 100644
--- a/src/dynarec/dynarec_native_functions.c
+++ b/src/dynarec/dynarec_native_functions.c
@@ -592,9 +592,11 @@ uint8_t geted_ib(dynarec_native_t* dyn, uintptr_t addr, int ninst, uint8_t nexto
 }
 #undef F8
 
-int isNativeCall(dynarec_native_t* dyn, uintptr_t addr, uintptr_t* calladdress, uint16_t* retn)
+int isNativeCall(dynarec_native_t* dyn, uintptr_t addr, int is32bits, uintptr_t* calladdress, uint16_t* retn)
 {
     (void)dyn;
+    if(is32bits)
+        addr &= 0xFFFFFFFFLL;
 
 #define PK(a)       *(uint8_t*)(addr+a)
 #define PK32(a)     *(int32_t*)(addr+a)
diff --git a/src/dynarec/dynarec_native_functions.h b/src/dynarec/dynarec_native_functions.h
index e9cff961..fe74c2b3 100644
--- a/src/dynarec/dynarec_native_functions.h
+++ b/src/dynarec/dynarec_native_functions.h
@@ -72,7 +72,7 @@ uintptr_t fakeed(dynarec_native_t* dyn, uintptr_t addr, int ninst, uint8_t nexto
 uint8_t geted_ib(dynarec_native_t* dyn, uintptr_t addr, int ninst, uint8_t nextop);
 
 // Is what pointed at addr a native call? And if yes, to what function?
-int isNativeCall(dynarec_native_t* dyn, uintptr_t addr, uintptr_t* calladdress, uint16_t* retn);
+int isNativeCall(dynarec_native_t* dyn, uintptr_t addr, int is32bits, uintptr_t* calladdress, uint16_t* retn);
 
 // AVX utilities
 void avx_mark_zero(dynarec_native_t* dyn, int ninst, int reg);
diff --git a/src/dynarec/la64/dynarec_la64_00.c b/src/dynarec/la64/dynarec_la64_00.c
index 8676b006..abbca1e9 100644
--- a/src/dynarec/la64/dynarec_la64_00.c
+++ b/src/dynarec/la64/dynarec_la64_00.c
@@ -1862,7 +1862,7 @@ uintptr_t dynarec64_00(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
 #endif
             }
 #if STEP < 2
-            if (!rex.is32bits && isNativeCall(dyn, addr + i32, &dyn->insts[ninst].natcall, &dyn->insts[ninst].retn))
+            if (!rex.is32bits && isNativeCall(dyn, addr + i32, rex.is32bits, &dyn->insts[ninst].natcall, &dyn->insts[ninst].retn))
                 tmp = dyn->insts[ninst].pass2choice = 3;
             else
                 tmp = dyn->insts[ninst].pass2choice = 0;
@@ -1969,7 +1969,11 @@ uintptr_t dynarec64_00(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
                         *ok = 0;
                         *need_epilog = 0;
                     }
-                    jump_to_next(dyn, addr + i32, 0, ninst, rex.is32bits);
+                    if(rex.is32bits)
+                        j64 = (uint32_t)(addr+i32);
+                    else
+                        j64 = addr+i32;
+                    jump_to_next(dyn, j64, 0, ninst, rex.is32bits);
                     break;
             }
             break;
@@ -1983,11 +1987,15 @@ uintptr_t dynarec64_00(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
                 INST_NAME("JMP Ib");
                 i32 = F8S;
             }
-            JUMP((uintptr_t)getAlternate((void*)(addr + i32)), 0);
+            if(rex.is32bits)
+                j64 = (uint32_t)(addr+i32);
+            else
+                j64 = addr+i32;
+            JUMP((uintptr_t)getAlternate((void*)j64), 0);
             if (dyn->insts[ninst].x64.jmp_insts == -1) {
                 // out of the block
                 fpu_purgecache(dyn, ninst, 1, x1, x2, x3);
-                jump_to_next(dyn, (uintptr_t)getAlternate((void*)(addr + i32)), 0, ninst, rex.is32bits);
+                jump_to_next(dyn, (uintptr_t)getAlternate((void*)j64), 0, ninst, rex.is32bits);
             } else {
                 // inside the block
                 CacheTransform(dyn, ninst, CHECK_CACHE(), x1, x2, x3);
diff --git a/src/dynarec/la64/dynarec_la64_0f.c b/src/dynarec/la64/dynarec_la64_0f.c
index eadd17aa..164f14ef 100644
--- a/src/dynarec/la64/dynarec_la64_0f.c
+++ b/src/dynarec/la64/dynarec_la64_0f.c
@@ -568,8 +568,12 @@ uintptr_t dynarec64_0F(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
         #define GO(GETFLAGS, NO, YES, F, I)                                                         \
             READFLAGS(F);                                                                           \
             i32_ = F32S;                                                                            \
+            if(rex.is32bits)                                                                        \
+                j64 = (uint32_t)(addr+i32_);                                                        \
+            else                                                                                    \
+                j64 = addr+i32_;                                                                    \
             BARRIER(BARRIER_MAYBE);                                                                 \
-            JUMP(addr + i32_, 1);                                                                   \
+            JUMP(j64, 1);                                                                           \
             if (la64_lbt) {                                                                         \
                 X64_SETJ(x1, I);                                                                    \
             } else {                                                                                \
@@ -585,7 +589,7 @@ uintptr_t dynarec64_0F(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
                 if (dyn->insts[ninst].x64.jmp_insts == -1) {                                        \
                     if (!(dyn->insts[ninst].x64.barrier & BARRIER_FLOAT))                           \
                         fpu_purgecache(dyn, ninst, 1, x1, x2, x3);                                  \
-                    jump_to_next(dyn, addr + i32_, 0, ninst, rex.is32bits);                         \
+                    jump_to_next(dyn, j64, 0, ninst, rex.is32bits);                                 \
                 } else {                                                                            \
                     CacheTransform(dyn, ninst, cacheupd, x1, x2, x3);                               \
                     i32 = dyn->insts[dyn->insts[ninst].x64.jmp_insts].address - (dyn->native_size); \
diff --git a/src/dynarec/rv64/dynarec_rv64_00_3.c b/src/dynarec/rv64/dynarec_rv64_00_3.c
index 24a42951..3288a73a 100644
--- a/src/dynarec/rv64/dynarec_rv64_00_3.c
+++ b/src/dynarec/rv64/dynarec_rv64_00_3.c
@@ -862,7 +862,7 @@ uintptr_t dynarec64_00_3(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
                 #endif
             }
             #if STEP < 2
-            if(!rex.is32bits && isNativeCall(dyn, addr+i32, &dyn->insts[ninst].natcall, &dyn->insts[ninst].retn))
+            if(!rex.is32bits && isNativeCall(dyn, addr+i32, rex.is32bits, &dyn->insts[ninst].natcall, &dyn->insts[ninst].retn))
                 tmp = dyn->insts[ninst].pass2choice = 3;
             else
                 tmp = dyn->insts[ninst].pass2choice = 0;
@@ -969,7 +969,11 @@ uintptr_t dynarec64_00_3(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
                         *ok = 0;
                         *need_epilog = 0;
                     }
-                    jump_to_next(dyn, addr+i32, 0, ninst, rex.is32bits);
+                    if(rex.is32bits)
+                        j64 = (uint32_t)(addr+i32);
+                    else
+                        j64 = addr+i32;
+                    jump_to_next(dyn, j64, 0, ninst, rex.is32bits);
                     break;
             }
             break;
@@ -983,11 +987,15 @@ uintptr_t dynarec64_00_3(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
                 INST_NAME("JMP Ib");
                 i32 = F8S;
             }
-            JUMP((uintptr_t)getAlternate((void*)(addr+i32)), 0);
+            if(rex.is32bits)
+                j64 = (uint32_t)(addr+i32);
+            else
+                j64 = addr+i32;
+            JUMP((uintptr_t)getAlternate((void*)j64), 0);
             if(dyn->insts[ninst].x64.jmp_insts==-1) {
                 // out of the block
                 fpu_purgecache(dyn, ninst, 1, x1, x2, x3);
-                jump_to_next(dyn, (uintptr_t)getAlternate((void*)(addr+i32)), 0, ninst, rex.is32bits);
+                jump_to_next(dyn, (uintptr_t)getAlternate((void*)j64), 0, ninst, rex.is32bits);
             } else {
                 // inside the block
                 CacheTransform(dyn, ninst, CHECK_CACHE(), x1, x2, x3);
diff --git a/src/dynarec/rv64/dynarec_rv64_helper.c b/src/dynarec/rv64/dynarec_rv64_helper.c
index 4be3f8ae..4fafa883 100644
--- a/src/dynarec/rv64/dynarec_rv64_helper.c
+++ b/src/dynarec/rv64/dynarec_rv64_helper.c
@@ -502,6 +502,9 @@ void jump_to_next(dynarec_rv64_t* dyn, uintptr_t ip, int reg, int ninst, int is3
     MAYUSE(dyn); MAYUSE(ninst);
     MESSAGE(LOG_DUMP, "Jump to next\n");
 
+    if(is32bits)
+        ip &= 0xffffffffLL;
+
     if(reg) {
         if(reg!=xRIP) {
             MV(xRIP, reg);