[DYNAREC] Make sure jump address is wrapped on 32bits address space

This commit is contained in:
ptitSeb 2024-09-16 16:10:29 +02:00
parent 1e8807ac0a
commit 446d57122c
9 changed files with 52 additions and 16 deletions

View File

@ -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;

View File

@ -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); \

View File

@ -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) {

View File

@ -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)

View File

@ -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);

View File

@ -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);

View File

@ -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); \

View File

@ -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);

View File

@ -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);