diff options
author | Mike Pall <mike> | 2010-02-24 01:29:11 +0100 |
---|---|---|
committer | Mike Pall <mike> | 2010-02-24 01:29:11 +0100 |
commit | 2f3a917f2f3f5e9efc710f6dcc8ea0b9540fc898 (patch) | |
tree | 071577f22ee4bffce4f18969f8d3e4c9e3506cb3 /src | |
parent | 47da0d8018c6fb512740be87fdc8a71c4b87d892 (diff) | |
download | luajit-2f3a917f2f3f5e9efc710f6dcc8ea0b9540fc898.tar.gz luajit-2f3a917f2f3f5e9efc710f6dcc8ea0b9540fc898.tar.bz2 luajit-2f3a917f2f3f5e9efc710f6dcc8ea0b9540fc898.zip |
Check relative jump distances for x64.
Diffstat (limited to 'src')
-rw-r--r-- | src/lj_asm.c | 27 |
1 files changed, 18 insertions, 9 deletions
diff --git a/src/lj_asm.c b/src/lj_asm.c index 6c5e4659..116c6e1f 100644 --- a/src/lj_asm.c +++ b/src/lj_asm.c | |||
@@ -183,7 +183,7 @@ static void emit_rr(ASMState *as, x86Op xo, Reg r1, Reg r2) | |||
183 | 183 | ||
184 | #if LJ_64 && defined(LUA_USE_ASSERT) | 184 | #if LJ_64 && defined(LUA_USE_ASSERT) |
185 | /* [addr] is sign-extended in x64 and must be in lower 2G (not 4G). */ | 185 | /* [addr] is sign-extended in x64 and must be in lower 2G (not 4G). */ |
186 | static int32_t ptr2addr(void *p) | 186 | static int32_t ptr2addr(const void *p) |
187 | { | 187 | { |
188 | lua_assert((uintptr_t)p < (uintptr_t)0x80000000); | 188 | lua_assert((uintptr_t)p < (uintptr_t)0x80000000); |
189 | return i32ptr(p); | 189 | return i32ptr(p); |
@@ -414,7 +414,9 @@ typedef MCode *MCLabel; | |||
414 | static void emit_sjcc(ASMState *as, int cc, MCLabel target) | 414 | static void emit_sjcc(ASMState *as, int cc, MCLabel target) |
415 | { | 415 | { |
416 | MCode *p = as->mcp; | 416 | MCode *p = as->mcp; |
417 | p[-1] = (MCode)(int8_t)(target-p); | 417 | ptrdiff_t delta = target - p; |
418 | lua_assert(delta == (int8_t)delta); | ||
419 | p[-1] = (MCode)(int8_t)delta; | ||
418 | p[-2] = (MCode)(XI_JCCs+(cc&15)); | 420 | p[-2] = (MCode)(XI_JCCs+(cc&15)); |
419 | as->mcp = p - 2; | 421 | as->mcp = p - 2; |
420 | } | 422 | } |
@@ -438,12 +440,19 @@ static void emit_sfixup(ASMState *as, MCLabel source) | |||
438 | /* Return label pointing to current PC. */ | 440 | /* Return label pointing to current PC. */ |
439 | #define emit_label(as) ((as)->mcp) | 441 | #define emit_label(as) ((as)->mcp) |
440 | 442 | ||
443 | /* Compute relative 32 bit offset for jump and call instructions. */ | ||
444 | static LJ_AINLINE int32_t jmprel(MCode *p, MCode *target) | ||
445 | { | ||
446 | ptrdiff_t delta = target - p; | ||
447 | lua_assert(delta == (int32_t)delta); | ||
448 | return (int32_t)delta; | ||
449 | } | ||
450 | |||
441 | /* jcc target */ | 451 | /* jcc target */ |
442 | static void emit_jcc(ASMState *as, int cc, MCode *target) | 452 | static void emit_jcc(ASMState *as, int cc, MCode *target) |
443 | { | 453 | { |
444 | MCode *p = as->mcp; | 454 | MCode *p = as->mcp; |
445 | int32_t addr = (int32_t)(target - p); | 455 | *(int32_t *)(p-4) = jmprel(p, target); |
446 | *(int32_t *)(p-4) = addr; | ||
447 | p[-5] = (MCode)(XI_JCCn+(cc&15)); | 456 | p[-5] = (MCode)(XI_JCCn+(cc&15)); |
448 | p[-6] = 0x0f; | 457 | p[-6] = 0x0f; |
449 | as->mcp = p - 6; | 458 | as->mcp = p - 6; |
@@ -453,7 +462,7 @@ static void emit_jcc(ASMState *as, int cc, MCode *target) | |||
453 | static void emit_call_(ASMState *as, MCode *target) | 462 | static void emit_call_(ASMState *as, MCode *target) |
454 | { | 463 | { |
455 | MCode *p = as->mcp; | 464 | MCode *p = as->mcp; |
456 | *(int32_t *)(p-4) = (int32_t)(target - p); | 465 | *(int32_t *)(p-4) = jmprel(p, target); |
457 | p[-5] = XI_CALL; | 466 | p[-5] = XI_CALL; |
458 | as->mcp = p - 5; | 467 | as->mcp = p - 5; |
459 | } | 468 | } |
@@ -925,7 +934,7 @@ static MCode *asm_exitstub_gen(ASMState *as, ExitNo group) | |||
925 | *(int32_t *)mxp = ptr2addr(J2GG(as->J)->dispatch); mxp += 4; | 934 | *(int32_t *)mxp = ptr2addr(J2GG(as->J)->dispatch); mxp += 4; |
926 | /* Jump to exit handler which fills in the ExitState. */ | 935 | /* Jump to exit handler which fills in the ExitState. */ |
927 | *mxp++ = XI_JMP; mxp += 4; | 936 | *mxp++ = XI_JMP; mxp += 4; |
928 | *((int32_t *)(mxp-4)) = (int32_t)((MCode *)lj_vm_exit_handler - mxp); | 937 | *((int32_t *)(mxp-4)) = jmprel(mxp, (MCode *)(void *)lj_vm_exit_handler); |
929 | /* Commit the code for this group (even if assembly fails later on). */ | 938 | /* Commit the code for this group (even if assembly fails later on). */ |
930 | lj_mcode_commitbot(as->J, mxp); | 939 | lj_mcode_commitbot(as->J, mxp); |
931 | as->mcbot = mxp; | 940 | as->mcbot = mxp; |
@@ -3165,7 +3174,7 @@ static void asm_tail_fixup(ASMState *as, TraceNo lnk) | |||
3165 | /* Patch exit branch. */ | 3174 | /* Patch exit branch. */ |
3166 | target = lnk == TRACE_INTERP ? (MCode *)lj_vm_exit_interp : | 3175 | target = lnk == TRACE_INTERP ? (MCode *)lj_vm_exit_interp : |
3167 | as->J->trace[lnk]->mcode; | 3176 | as->J->trace[lnk]->mcode; |
3168 | *(int32_t *)(p-4) = (int32_t)(target - p); | 3177 | *(int32_t *)(p-4) = jmprel(p, target); |
3169 | p[-5] = XI_JMP; | 3178 | p[-5] = XI_JMP; |
3170 | /* Drop unused mcode tail. Fill with NOPs to make the prefetcher happy. */ | 3179 | /* Drop unused mcode tail. Fill with NOPs to make the prefetcher happy. */ |
3171 | for (q = as->mctop-1; q >= p; q--) | 3180 | for (q = as->mctop-1; q >= p; q--) |
@@ -3533,7 +3542,7 @@ void lj_asm_patchexit(jit_State *J, Trace *T, ExitNo exitno, MCode *target) | |||
3533 | MCode *pe = p+len-6; | 3542 | MCode *pe = p+len-6; |
3534 | uint32_t stateaddr = u32ptr(&J2G(J)->vmstate); | 3543 | uint32_t stateaddr = u32ptr(&J2G(J)->vmstate); |
3535 | if (len > 5 && p[len-5] == XI_JMP && p+len-6 + *(int32_t *)(p+len-4) == px) | 3544 | if (len > 5 && p[len-5] == XI_JMP && p+len-6 + *(int32_t *)(p+len-4) == px) |
3536 | *(int32_t *)(p+len-4) = (int32_t)(target - (p+len)); | 3545 | *(int32_t *)(p+len-4) = jmprel(p+len, target); |
3537 | /* Do not patch parent exit for a stack check. Skip beyond vmstate update. */ | 3546 | /* Do not patch parent exit for a stack check. Skip beyond vmstate update. */ |
3538 | for (; p < pe; p++) | 3547 | for (; p < pe; p++) |
3539 | if (*(uint32_t *)(p+(LJ_64 ? 3 : 2)) == stateaddr && p[0] == XI_MOVmi) { | 3548 | if (*(uint32_t *)(p+(LJ_64 ? 3 : 2)) == stateaddr && p[0] == XI_MOVmi) { |
@@ -3543,7 +3552,7 @@ void lj_asm_patchexit(jit_State *J, Trace *T, ExitNo exitno, MCode *target) | |||
3543 | lua_assert(p < pe); | 3552 | lua_assert(p < pe); |
3544 | for (; p < pe; p++) { | 3553 | for (; p < pe; p++) { |
3545 | if ((*(uint16_t *)p & 0xf0ff) == 0x800f && p + *(int32_t *)(p+2) == px) { | 3554 | if ((*(uint16_t *)p & 0xf0ff) == 0x800f && p + *(int32_t *)(p+2) == px) { |
3546 | *(int32_t *)(p+2) = (int32_t)(target - (p+6)); | 3555 | *(int32_t *)(p+2) = jmprel(p+6, target); |
3547 | p += 5; | 3556 | p += 5; |
3548 | } | 3557 | } |
3549 | } | 3558 | } |