Skip to content

Commit

Permalink
[DYNAREC] Make sure jump address is wrapped on 32bits address space
Browse files Browse the repository at this point in the history
  • Loading branch information
ptitSeb committed Sep 16, 2024
1 parent 1e8807a commit 446d571
Show file tree
Hide file tree
Showing 9 changed files with 52 additions and 16 deletions.
8 changes: 6 additions & 2 deletions src/dynarec/arm64/dynarec_arm64_00.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down
8 changes: 6 additions & 2 deletions src/dynarec/arm64/dynarec_arm64_0f.c
Original file line number Diff line number Diff line change
Expand Up @@ -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()) { \
Expand All @@ -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); \
Expand Down
3 changes: 3 additions & 0 deletions src/dynarec/arm64/dynarec_arm64_helper.c
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
4 changes: 3 additions & 1 deletion src/dynarec/dynarec_native_functions.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
2 changes: 1 addition & 1 deletion src/dynarec/dynarec_native_functions.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
16 changes: 12 additions & 4 deletions src/dynarec/la64/dynarec_la64_00.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand All @@ -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);
Expand Down
8 changes: 6 additions & 2 deletions src/dynarec/la64/dynarec_la64_0f.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 { \
Expand All @@ -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); \
Expand Down
16 changes: 12 additions & 4 deletions src/dynarec/rv64/dynarec_rv64_00_3.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand All @@ -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);
Expand Down
3 changes: 3 additions & 0 deletions src/dynarec/rv64/dynarec_rv64_helper.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down

0 comments on commit 446d571

Please sign in to comment.