diff options
author | Mike Pall <mike> | 2020-09-27 16:44:13 +0200 |
---|---|---|
committer | Mike Pall <mike> | 2020-09-27 16:44:13 +0200 |
commit | e8ec6fe996cf48ef23755581dafe372eb71ad75c (patch) | |
tree | 69e0d40f53cf99bfa9f12e8dbd09a7badccacba7 /src/lj_asm_x86.h | |
parent | 881d02d3117838acaf4fb844332c8e33cc95c8c5 (diff) | |
download | luajit-e8ec6fe996cf48ef23755581dafe372eb71ad75c.tar.gz luajit-e8ec6fe996cf48ef23755581dafe372eb71ad75c.tar.bz2 luajit-e8ec6fe996cf48ef23755581dafe372eb71ad75c.zip |
Prevent patching of the GC exit check branch.
Reported by Arseny Vakhrushev.
Diffstat (limited to 'src/lj_asm_x86.h')
-rw-r--r-- | src/lj_asm_x86.h | 11 |
1 files changed, 9 insertions, 2 deletions
diff --git a/src/lj_asm_x86.h b/src/lj_asm_x86.h index 68b40b31..9b61b397 100644 --- a/src/lj_asm_x86.h +++ b/src/lj_asm_x86.h | |||
@@ -2884,6 +2884,7 @@ void lj_asm_patchexit(jit_State *J, GCtrace *T, ExitNo exitno, MCode *target) | |||
2884 | MSize len = T->szmcode; | 2884 | MSize len = T->szmcode; |
2885 | MCode *px = exitstub_addr(J, exitno) - 6; | 2885 | MCode *px = exitstub_addr(J, exitno) - 6; |
2886 | MCode *pe = p+len-6; | 2886 | MCode *pe = p+len-6; |
2887 | MCode *pgc = NULL; | ||
2887 | uint32_t stateaddr = u32ptr(&J2G(J)->vmstate); | 2888 | uint32_t stateaddr = u32ptr(&J2G(J)->vmstate); |
2888 | if (len > 5 && p[len-5] == XI_JMP && p+len-6 + *(int32_t *)(p+len-4) == px) | 2889 | if (len > 5 && p[len-5] == XI_JMP && p+len-6 + *(int32_t *)(p+len-4) == px) |
2889 | *(int32_t *)(p+len-4) = jmprel(p+len, target); | 2890 | *(int32_t *)(p+len-4) = jmprel(p+len, target); |
@@ -2892,9 +2893,15 @@ void lj_asm_patchexit(jit_State *J, GCtrace *T, ExitNo exitno, MCode *target) | |||
2892 | if (*(uint32_t *)(p+(LJ_64 ? 3 : 2)) == stateaddr && p[0] == XI_MOVmi) | 2893 | if (*(uint32_t *)(p+(LJ_64 ? 3 : 2)) == stateaddr && p[0] == XI_MOVmi) |
2893 | break; | 2894 | break; |
2894 | lua_assert(p < pe); | 2895 | lua_assert(p < pe); |
2895 | for (; p < pe; p += asm_x86_inslen(p)) | 2896 | for (; p < pe; p += asm_x86_inslen(p)) { |
2896 | if ((*(uint16_t *)p & 0xf0ff) == 0x800f && p + *(int32_t *)(p+2) == px) | 2897 | if ((*(uint16_t *)p & 0xf0ff) == 0x800f && p + *(int32_t *)(p+2) == px && |
2898 | p != pgc) { | ||
2897 | *(int32_t *)(p+2) = jmprel(p+6, target); | 2899 | *(int32_t *)(p+2) = jmprel(p+6, target); |
2900 | } else if (*p == XI_CALL && | ||
2901 | (void *)(p+5+*(int32_t *)(p+1)) == (void *)lj_gc_step_jit) { | ||
2902 | pgc = p+7; /* Do not patch GC check exit. */ | ||
2903 | } | ||
2904 | } | ||
2898 | lj_mcode_sync(T->mcode, T->mcode + T->szmcode); | 2905 | lj_mcode_sync(T->mcode, T->mcode + T->szmcode); |
2899 | lj_mcode_patch(J, mcarea, 1); | 2906 | lj_mcode_patch(J, mcarea, 1); |
2900 | } | 2907 | } |