diff options
| author | Mike Pall <mike> | 2021-03-23 00:26:08 +0100 |
|---|---|---|
| committer | Mike Pall <mike> | 2021-03-23 00:26:08 +0100 |
| commit | dbb78630169a8106b355a5be8af627e98c362f1e (patch) | |
| tree | a5db8abc676432cb66d36923f04aef1271c54e2e /src | |
| parent | e131936133c58de4426c595db2341caf5a1665b5 (diff) | |
| download | luajit-dbb78630169a8106b355a5be8af627e98c362f1e.tar.gz luajit-dbb78630169a8106b355a5be8af627e98c362f1e.tar.bz2 luajit-dbb78630169a8106b355a5be8af627e98c362f1e.zip | |
MIPS: Fix handling of long-range spare jumps.
Diffstat (limited to 'src')
| -rw-r--r-- | src/lj_asm_mips.h | 48 | ||||
| -rw-r--r-- | src/lj_mcode.c | 11 |
2 files changed, 34 insertions, 25 deletions
diff --git a/src/lj_asm_mips.h b/src/lj_asm_mips.h index 321d63c0..a3ab2f8e 100644 --- a/src/lj_asm_mips.h +++ b/src/lj_asm_mips.h | |||
| @@ -64,19 +64,31 @@ static Reg ra_alloc2(ASMState *as, IRIns *ir, RegSet allow) | |||
| 64 | /* Setup spare long-range jump slots per mcarea. */ | 64 | /* Setup spare long-range jump slots per mcarea. */ |
| 65 | static void asm_sparejump_setup(ASMState *as) | 65 | static void asm_sparejump_setup(ASMState *as) |
| 66 | { | 66 | { |
| 67 | MCode *mxp = as->mcbot; | 67 | MCode *mxp = as->mctop; |
| 68 | if (((uintptr_t)mxp & (LJ_PAGESIZE-1)) == sizeof(MCLink)) { | 68 | if ((char *)mxp == (char *)as->J->mcarea + as->J->szmcarea) { |
| 69 | mxp -= MIPS_SPAREJUMP*2; | ||
| 69 | lj_assertA(MIPSI_NOP == 0, "bad NOP"); | 70 | lj_assertA(MIPSI_NOP == 0, "bad NOP"); |
| 70 | memset(mxp, 0, MIPS_SPAREJUMP*2*sizeof(MCode)); | 71 | memset(mxp, 0, MIPS_SPAREJUMP*2*sizeof(MCode)); |
| 71 | mxp += MIPS_SPAREJUMP*2; | 72 | as->mctop = mxp; |
| 72 | lj_assertA(mxp < as->mctop, "MIPS_SPAREJUMP too big"); | ||
| 73 | lj_mcode_sync(as->mcbot, mxp); | ||
| 74 | lj_mcode_commitbot(as->J, mxp); | ||
| 75 | as->mcbot = mxp; | ||
| 76 | as->mclim = as->mcbot + MCLIM_REDZONE; | ||
| 77 | } | 73 | } |
| 78 | } | 74 | } |
| 79 | 75 | ||
| 76 | static MCode *asm_sparejump_use(MCode *mcarea, MCode tjump) | ||
| 77 | { | ||
| 78 | MCode *mxp = (MCode *)((char *)mcarea + ((MCLink *)mcarea)->size); | ||
| 79 | int slot = MIPS_SPAREJUMP; | ||
| 80 | while (slot--) { | ||
| 81 | mxp -= 2; | ||
| 82 | if (*mxp == tjump) { | ||
| 83 | return mxp; | ||
| 84 | } else if (*mxp == MIPSI_NOP) { | ||
| 85 | *mxp = tjump; | ||
| 86 | return mxp; | ||
| 87 | } | ||
| 88 | } | ||
| 89 | return NULL; | ||
| 90 | } | ||
| 91 | |||
| 80 | /* Setup exit stub after the end of each trace. */ | 92 | /* Setup exit stub after the end of each trace. */ |
| 81 | static void asm_exitstub_setup(ASMState *as) | 93 | static void asm_exitstub_setup(ASMState *as) |
| 82 | { | 94 | { |
| @@ -2704,21 +2716,17 @@ void lj_asm_patchexit(jit_State *J, GCtrace *T, ExitNo exitno, MCode *target) | |||
| 2704 | patchbranch: | 2716 | patchbranch: |
| 2705 | p[-1] = (p[-1] & 0xffff0000u) | (delta & 0xffffu); | 2717 | p[-1] = (p[-1] & 0xffff0000u) | (delta & 0xffffu); |
| 2706 | *p = MIPSI_NOP; /* Replace the load of the exit number. */ | 2718 | *p = MIPSI_NOP; /* Replace the load of the exit number. */ |
| 2707 | cstop = p; | 2719 | cstop = p+1; |
| 2708 | if (!cstart) cstart = p-1; | 2720 | if (!cstart) cstart = p-1; |
| 2709 | } else { /* Branch out of range. Use spare jump slot in mcarea. */ | 2721 | } else { /* Branch out of range. Use spare jump slot in mcarea. */ |
| 2710 | int i; | 2722 | MCode *mcjump = asm_sparejump_use(mcarea, tjump); |
| 2711 | for (i = (int)(sizeof(MCLink)/sizeof(MCode)); | 2723 | if (mcjump) { |
| 2712 | i < (int)(sizeof(MCLink)/sizeof(MCode)+MIPS_SPAREJUMP*2); | 2724 | lj_mcode_sync(mcjump, mcjump+1); |
| 2713 | i += 2) { | 2725 | delta = mcjump - p; |
| 2714 | if (mcarea[i] == tjump) { | 2726 | if (((delta + 0x8000) >> 16) == 0) { |
| 2715 | delta = mcarea+i - p; | ||
| 2716 | goto patchbranch; | ||
| 2717 | } else if (mcarea[i] == MIPSI_NOP) { | ||
| 2718 | mcarea[i] = tjump; | ||
| 2719 | cstart = mcarea+i; | ||
| 2720 | delta = mcarea+i - p; | ||
| 2721 | goto patchbranch; | 2727 | goto patchbranch; |
| 2728 | } else { | ||
| 2729 | lj_assertJ(0, "spare jump out of range: -Osizemcode too big"); | ||
| 2722 | } | 2730 | } |
| 2723 | } | 2731 | } |
| 2724 | /* Ignore jump slot overflow. Child trace is simply not attached. */ | 2732 | /* Ignore jump slot overflow. Child trace is simply not attached. */ |
diff --git a/src/lj_mcode.c b/src/lj_mcode.c index 9ce1deec..fc67eaee 100644 --- a/src/lj_mcode.c +++ b/src/lj_mcode.c | |||
| @@ -314,21 +314,21 @@ void lj_mcode_abort(jit_State *J) | |||
| 314 | /* Set/reset protection to allow patching of MCode areas. */ | 314 | /* Set/reset protection to allow patching of MCode areas. */ |
| 315 | MCode *lj_mcode_patch(jit_State *J, MCode *ptr, int finish) | 315 | MCode *lj_mcode_patch(jit_State *J, MCode *ptr, int finish) |
| 316 | { | 316 | { |
| 317 | #if LUAJIT_SECURITY_MCODE == 0 | ||
| 318 | UNUSED(J); UNUSED(ptr); UNUSED(finish); | ||
| 319 | return NULL; | ||
| 320 | #else | ||
| 321 | if (finish) { | 317 | if (finish) { |
| 318 | #if LUAJIT_SECURITY_MCODE | ||
| 322 | if (J->mcarea == ptr) | 319 | if (J->mcarea == ptr) |
| 323 | mcode_protect(J, MCPROT_RUN); | 320 | mcode_protect(J, MCPROT_RUN); |
| 324 | else if (LJ_UNLIKELY(mcode_setprot(ptr, ((MCLink *)ptr)->size, MCPROT_RUN))) | 321 | else if (LJ_UNLIKELY(mcode_setprot(ptr, ((MCLink *)ptr)->size, MCPROT_RUN))) |
| 325 | mcode_protfail(J); | 322 | mcode_protfail(J); |
| 323 | #endif | ||
| 326 | return NULL; | 324 | return NULL; |
| 327 | } else { | 325 | } else { |
| 328 | MCode *mc = J->mcarea; | 326 | MCode *mc = J->mcarea; |
| 329 | /* Try current area first to use the protection cache. */ | 327 | /* Try current area first to use the protection cache. */ |
| 330 | if (ptr >= mc && ptr < (MCode *)((char *)mc + J->szmcarea)) { | 328 | if (ptr >= mc && ptr < (MCode *)((char *)mc + J->szmcarea)) { |
| 329 | #if LUAJIT_SECURITY_MCODE | ||
| 331 | mcode_protect(J, MCPROT_GEN); | 330 | mcode_protect(J, MCPROT_GEN); |
| 331 | #endif | ||
| 332 | return mc; | 332 | return mc; |
| 333 | } | 333 | } |
| 334 | /* Otherwise search through the list of MCode areas. */ | 334 | /* Otherwise search through the list of MCode areas. */ |
| @@ -336,13 +336,14 @@ MCode *lj_mcode_patch(jit_State *J, MCode *ptr, int finish) | |||
| 336 | mc = ((MCLink *)mc)->next; | 336 | mc = ((MCLink *)mc)->next; |
| 337 | lj_assertJ(mc != NULL, "broken MCode area chain"); | 337 | lj_assertJ(mc != NULL, "broken MCode area chain"); |
| 338 | if (ptr >= mc && ptr < (MCode *)((char *)mc + ((MCLink *)mc)->size)) { | 338 | if (ptr >= mc && ptr < (MCode *)((char *)mc + ((MCLink *)mc)->size)) { |
| 339 | #if LUAJIT_SECURITY_MCODE | ||
| 339 | if (LJ_UNLIKELY(mcode_setprot(mc, ((MCLink *)mc)->size, MCPROT_GEN))) | 340 | if (LJ_UNLIKELY(mcode_setprot(mc, ((MCLink *)mc)->size, MCPROT_GEN))) |
| 340 | mcode_protfail(J); | 341 | mcode_protfail(J); |
| 342 | #endif | ||
| 341 | return mc; | 343 | return mc; |
| 342 | } | 344 | } |
| 343 | } | 345 | } |
| 344 | } | 346 | } |
| 345 | #endif | ||
| 346 | } | 347 | } |
| 347 | 348 | ||
| 348 | /* Limit of MCode reservation reached. */ | 349 | /* Limit of MCode reservation reached. */ |
