mirror of
https://github.com/LuaJIT/LuaJIT.git
synced 2025-02-07 23:24:09 +00:00
MIPS: Fix handling of long-range spare jumps.
This commit is contained in:
parent
e131936133
commit
dbb7863016
@ -64,19 +64,31 @@ static Reg ra_alloc2(ASMState *as, IRIns *ir, RegSet allow)
|
||||
/* Setup spare long-range jump slots per mcarea. */
|
||||
static void asm_sparejump_setup(ASMState *as)
|
||||
{
|
||||
MCode *mxp = as->mcbot;
|
||||
if (((uintptr_t)mxp & (LJ_PAGESIZE-1)) == sizeof(MCLink)) {
|
||||
MCode *mxp = as->mctop;
|
||||
if ((char *)mxp == (char *)as->J->mcarea + as->J->szmcarea) {
|
||||
mxp -= MIPS_SPAREJUMP*2;
|
||||
lj_assertA(MIPSI_NOP == 0, "bad NOP");
|
||||
memset(mxp, 0, MIPS_SPAREJUMP*2*sizeof(MCode));
|
||||
mxp += MIPS_SPAREJUMP*2;
|
||||
lj_assertA(mxp < as->mctop, "MIPS_SPAREJUMP too big");
|
||||
lj_mcode_sync(as->mcbot, mxp);
|
||||
lj_mcode_commitbot(as->J, mxp);
|
||||
as->mcbot = mxp;
|
||||
as->mclim = as->mcbot + MCLIM_REDZONE;
|
||||
as->mctop = mxp;
|
||||
}
|
||||
}
|
||||
|
||||
static MCode *asm_sparejump_use(MCode *mcarea, MCode tjump)
|
||||
{
|
||||
MCode *mxp = (MCode *)((char *)mcarea + ((MCLink *)mcarea)->size);
|
||||
int slot = MIPS_SPAREJUMP;
|
||||
while (slot--) {
|
||||
mxp -= 2;
|
||||
if (*mxp == tjump) {
|
||||
return mxp;
|
||||
} else if (*mxp == MIPSI_NOP) {
|
||||
*mxp = tjump;
|
||||
return mxp;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Setup exit stub after the end of each trace. */
|
||||
static void asm_exitstub_setup(ASMState *as)
|
||||
{
|
||||
@ -2704,21 +2716,17 @@ void lj_asm_patchexit(jit_State *J, GCtrace *T, ExitNo exitno, MCode *target)
|
||||
patchbranch:
|
||||
p[-1] = (p[-1] & 0xffff0000u) | (delta & 0xffffu);
|
||||
*p = MIPSI_NOP; /* Replace the load of the exit number. */
|
||||
cstop = p;
|
||||
cstop = p+1;
|
||||
if (!cstart) cstart = p-1;
|
||||
} else { /* Branch out of range. Use spare jump slot in mcarea. */
|
||||
int i;
|
||||
for (i = (int)(sizeof(MCLink)/sizeof(MCode));
|
||||
i < (int)(sizeof(MCLink)/sizeof(MCode)+MIPS_SPAREJUMP*2);
|
||||
i += 2) {
|
||||
if (mcarea[i] == tjump) {
|
||||
delta = mcarea+i - p;
|
||||
goto patchbranch;
|
||||
} else if (mcarea[i] == MIPSI_NOP) {
|
||||
mcarea[i] = tjump;
|
||||
cstart = mcarea+i;
|
||||
delta = mcarea+i - p;
|
||||
MCode *mcjump = asm_sparejump_use(mcarea, tjump);
|
||||
if (mcjump) {
|
||||
lj_mcode_sync(mcjump, mcjump+1);
|
||||
delta = mcjump - p;
|
||||
if (((delta + 0x8000) >> 16) == 0) {
|
||||
goto patchbranch;
|
||||
} else {
|
||||
lj_assertJ(0, "spare jump out of range: -Osizemcode too big");
|
||||
}
|
||||
}
|
||||
/* Ignore jump slot overflow. Child trace is simply not attached. */
|
||||
|
@ -314,21 +314,21 @@ void lj_mcode_abort(jit_State *J)
|
||||
/* Set/reset protection to allow patching of MCode areas. */
|
||||
MCode *lj_mcode_patch(jit_State *J, MCode *ptr, int finish)
|
||||
{
|
||||
#if LUAJIT_SECURITY_MCODE == 0
|
||||
UNUSED(J); UNUSED(ptr); UNUSED(finish);
|
||||
return NULL;
|
||||
#else
|
||||
if (finish) {
|
||||
#if LUAJIT_SECURITY_MCODE
|
||||
if (J->mcarea == ptr)
|
||||
mcode_protect(J, MCPROT_RUN);
|
||||
else if (LJ_UNLIKELY(mcode_setprot(ptr, ((MCLink *)ptr)->size, MCPROT_RUN)))
|
||||
mcode_protfail(J);
|
||||
#endif
|
||||
return NULL;
|
||||
} else {
|
||||
MCode *mc = J->mcarea;
|
||||
/* Try current area first to use the protection cache. */
|
||||
if (ptr >= mc && ptr < (MCode *)((char *)mc + J->szmcarea)) {
|
||||
#if LUAJIT_SECURITY_MCODE
|
||||
mcode_protect(J, MCPROT_GEN);
|
||||
#endif
|
||||
return mc;
|
||||
}
|
||||
/* Otherwise search through the list of MCode areas. */
|
||||
@ -336,13 +336,14 @@ MCode *lj_mcode_patch(jit_State *J, MCode *ptr, int finish)
|
||||
mc = ((MCLink *)mc)->next;
|
||||
lj_assertJ(mc != NULL, "broken MCode area chain");
|
||||
if (ptr >= mc && ptr < (MCode *)((char *)mc + ((MCLink *)mc)->size)) {
|
||||
#if LUAJIT_SECURITY_MCODE
|
||||
if (LJ_UNLIKELY(mcode_setprot(mc, ((MCLink *)mc)->size, MCPROT_GEN)))
|
||||
mcode_protfail(J);
|
||||
#endif
|
||||
return mc;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Limit of MCode reservation reached. */
|
||||
|
Loading…
Reference in New Issue
Block a user