aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Pall <mike>2025-10-16 14:24:52 +0200
committerMike Pall <mike>2025-10-16 14:24:52 +0200
commit25a61a182166fec06f1a1a025eb8fabbb6cf483e (patch)
treeda55c519b1302d3a1eb082b5acf1b11e57cbd268
parent5c3254d68d2579bf8c5bd1e39e612582fb5a04f6 (diff)
downloadluajit-25a61a182166fec06f1a1a025eb8fabbb6cf483e.tar.gz
luajit-25a61a182166fec06f1a1a025eb8fabbb6cf483e.tar.bz2
luajit-25a61a182166fec06f1a1a025eb8fabbb6cf483e.zip
x64: Add support for CET IBT.
Note: this is not enabled by default, look for CET in lj_arch.h Contributed by Yuichiro Naito. #1391
-rw-r--r--src/Makefile4
-rw-r--r--src/jit/dis_x86.lua20
-rw-r--r--src/lj_arch.h11
-rw-r--r--src/lj_asm.c3
-rw-r--r--src/lj_emit_x86.h7
-rw-r--r--src/lj_target_x86.h3
-rw-r--r--src/vm_x64.dasc57
7 files changed, 95 insertions, 10 deletions
diff --git a/src/Makefile b/src/Makefile
index 5dd98a31..d23e0db2 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -446,6 +446,10 @@ ifneq (,$(findstring LJ_ABI_PAUTH 1,$(TARGET_TESTARCH)))
446 DASM_AFLAGS+= -D PAUTH 446 DASM_AFLAGS+= -D PAUTH
447 TARGET_ARCH+= -DLJ_ABI_PAUTH=1 447 TARGET_ARCH+= -DLJ_ABI_PAUTH=1
448endif 448endif
449ifneq (,$(findstring LJ_CET_BR 1,$(TARGET_TESTARCH)))
450 DASM_AFLAGS+= -D CET_BR
451 TARGET_ARCH+= -DLJ_CET_BR=1
452endif
449DASM_AFLAGS+= -D VER=$(subst LJ_ARCH_VERSION_,,$(filter LJ_ARCH_VERSION_%,$(subst LJ_ARCH_VERSION ,LJ_ARCH_VERSION_,$(TARGET_TESTARCH)))) 453DASM_AFLAGS+= -D VER=$(subst LJ_ARCH_VERSION_,,$(filter LJ_ARCH_VERSION_%,$(subst LJ_ARCH_VERSION ,LJ_ARCH_VERSION_,$(TARGET_TESTARCH))))
450ifeq (Windows,$(TARGET_SYS)) 454ifeq (Windows,$(TARGET_SYS))
451 DASM_AFLAGS+= -D WIN 455 DASM_AFLAGS+= -D WIN
diff --git a/src/jit/dis_x86.lua b/src/jit/dis_x86.lua
index b1de0eea..6b04ee84 100644
--- a/src/jit/dis_x86.lua
+++ b/src/jit/dis_x86.lua
@@ -122,7 +122,7 @@ local map_opc2 = {
122"movlhpsXrm$movhpsXrm|movshdupXrm|movhpdXrm", 122"movlhpsXrm$movhpsXrm|movshdupXrm|movhpdXrm",
123"movhpsXmr||movhpdXmr", 123"movhpsXmr||movhpdXmr",
124"$prefetcht!Bm","hintnopVm","hintnopVm","hintnopVm", 124"$prefetcht!Bm","hintnopVm","hintnopVm","hintnopVm",
125"hintnopVm","hintnopVm","hintnopVm","hintnopVm", 125"hintnopVm","hintnopVm","endbr*hintnopVm","hintnopVm",
126--2x 126--2x
127"movUmx$","movUmy$","movUxm$","movUym$","movUmz$",nil,"movUzm$",nil, 127"movUmx$","movUmy$","movUxm$","movUym$","movUmz$",nil,"movUzm$",nil,
128"movapsXrm||movapdXrm", 128"movapsXrm||movapdXrm",
@@ -804,6 +804,24 @@ map_act = {
804 return dispatch(ctx, map_opcvm[ctx.mrm]) 804 return dispatch(ctx, map_opcvm[ctx.mrm])
805 end, 805 end,
806 806
807 -- Special NOP for endbr64/endbr32.
808 endbr = function(ctx, name, pat)
809 if ctx.rep then
810 local pos = ctx.pos
811 local b = byte(ctx.code, pos)
812 local text
813 if b == 0xfa then text = "endbr64"
814 elseif b == 0xfb then text = "endbr64"
815 end
816 if text then
817 ctx.pos = pos + 1
818 ctx.rep = nil
819 return putop(ctx, text)
820 end
821 end
822 return dispatch(ctx, pat)
823 end,
824
807 -- Floating point opcode dispatch. 825 -- Floating point opcode dispatch.
808 fp = function(ctx, name, pat) 826 fp = function(ctx, name, pat)
809 local mrm = getmrm(ctx); if not mrm then return incomplete(ctx) end 827 local mrm = getmrm(ctx); if not mrm then return incomplete(ctx) end
diff --git a/src/lj_arch.h b/src/lj_arch.h
index 865bfa23..42c65879 100644
--- a/src/lj_arch.h
+++ b/src/lj_arch.h
@@ -219,6 +219,17 @@
219#error "macOS requires GC64 -- don't disable it" 219#error "macOS requires GC64 -- don't disable it"
220#endif 220#endif
221 221
222#if (__CET__ & 1) && defined(LUAJIT_ENABLE_CET_BR)
223/*
224** Control-Flow Enforcement Technique (CET) indirect branch tracking (IBT).
225** This is not enabled by default because it causes a notable slowdown of
226** the interpreter on all x64 CPUs, whether they have CET enabled or not.
227** If your toolchain enables -fcf-protection=branch by default, you need
228** to build with: make XCFLAGS=-DLUAJIT_ENABLE_CET_BR
229*/
230#define LJ_CET_BR 1
231#endif
232
222#elif LUAJIT_TARGET == LUAJIT_ARCH_ARM 233#elif LUAJIT_TARGET == LUAJIT_ARCH_ARM
223 234
224#define LJ_ARCH_NAME "arm" 235#define LJ_ARCH_NAME "arm"
diff --git a/src/lj_asm.c b/src/lj_asm.c
index fec43512..e7f3ec1c 100644
--- a/src/lj_asm.c
+++ b/src/lj_asm.c
@@ -2586,6 +2586,9 @@ void lj_asm_trace(jit_State *J, GCtrace *T)
2586 asm_head_side(as); 2586 asm_head_side(as);
2587 else 2587 else
2588 asm_head_root(as); 2588 asm_head_root(as);
2589#if LJ_CET_BR
2590 emit_endbr(as);
2591#endif
2589 asm_phi_fixup(as); 2592 asm_phi_fixup(as);
2590 2593
2591 if (J->curfinal->nins >= T->nins) { /* IR didn't grow? */ 2594 if (J->curfinal->nins >= T->nins) { /* IR didn't grow? */
diff --git a/src/lj_emit_x86.h b/src/lj_emit_x86.h
index f4773011..848301bc 100644
--- a/src/lj_emit_x86.h
+++ b/src/lj_emit_x86.h
@@ -70,6 +70,13 @@ static LJ_AINLINE MCode *emit_op(x86Op xo, Reg rr, Reg rb, Reg rx,
70 return p; 70 return p;
71} 71}
72 72
73#if LJ_CET_BR
74static void emit_endbr(ASMState *as)
75{
76 emit_u32(as, XI_ENDBR64);
77}
78#endif
79
73/* op + modrm */ 80/* op + modrm */
74#define emit_opm(xo, mode, rr, rb, p, delta) \ 81#define emit_opm(xo, mode, rr, rb, p, delta) \
75 (p[(delta)-1] = MODRM((mode), (rr), (rb)), \ 82 (p[(delta)-1] = MODRM((mode), (rr), (rb)), \
diff --git a/src/lj_target_x86.h b/src/lj_target_x86.h
index 6a528e82..fa32a5d4 100644
--- a/src/lj_target_x86.h
+++ b/src/lj_target_x86.h
@@ -242,6 +242,9 @@ typedef enum {
242 XV_SHLX = XV_660f38(f7), 242 XV_SHLX = XV_660f38(f7),
243 XV_SHRX = XV_f20f38(f7), 243 XV_SHRX = XV_f20f38(f7),
244 244
245 /* Special NOP instructions. */
246 XI_ENDBR64 = 0xfa1e0ff3,
247
245 /* Variable-length opcodes. XO_* prefix. */ 248 /* Variable-length opcodes. XO_* prefix. */
246 XO_OR = XO_(0b), 249 XO_OR = XO_(0b),
247 XO_MOV = XO_(8b), 250 XO_MOV = XO_(8b),
diff --git a/src/vm_x64.dasc b/src/vm_x64.dasc
index f501495b..52ef88af 100644
--- a/src/vm_x64.dasc
+++ b/src/vm_x64.dasc
@@ -189,16 +189,24 @@
189| 189|
190|.endif 190|.endif
191| 191|
192|//-- Control-Flow Enforcement Technique (CET) ---------------------------
193|
194|.if CET_BR
195|.macro endbr; endbr64; .endmacro
196|.else
197|.macro endbr; .endmacro
198|.endif
199|
192|//----------------------------------------------------------------------- 200|//-----------------------------------------------------------------------
193| 201|
194|// Instruction headers. 202|// Instruction headers.
195|.macro ins_A; .endmacro 203|.macro ins_A; endbr; .endmacro
196|.macro ins_AD; .endmacro 204|.macro ins_AD; endbr; .endmacro
197|.macro ins_AJ; .endmacro 205|.macro ins_AJ; endbr; .endmacro
198|.macro ins_ABC; movzx RBd, RCH; movzx RCd, RCL; .endmacro 206|.macro ins_ABC; endbr; movzx RBd, RCH; movzx RCd, RCL; .endmacro
199|.macro ins_AB_; movzx RBd, RCH; .endmacro 207|.macro ins_AB_; endbr; movzx RBd, RCH; .endmacro
200|.macro ins_A_C; movzx RCd, RCL; .endmacro 208|.macro ins_A_C; endbr; movzx RCd, RCL; .endmacro
201|.macro ins_AND; not RD; .endmacro 209|.macro ins_AND; endbr; not RD; .endmacro
202| 210|
203|// Instruction decode+dispatch. Carefully tuned (nope, lodsd is not faster). 211|// Instruction decode+dispatch. Carefully tuned (nope, lodsd is not faster).
204|.macro ins_NEXT 212|.macro ins_NEXT
@@ -479,20 +487,24 @@ static void build_subroutines(BuildCtx *ctx)
479 | jmp <3 487 | jmp <3
480 | 488 |
481 |->vm_unwind_yield: 489 |->vm_unwind_yield:
490 | endbr
482 | mov al, LUA_YIELD 491 | mov al, LUA_YIELD
483 | jmp ->vm_unwind_c_eh 492 | jmp ->vm_unwind_c_eh
484 | 493 |
485 |->vm_unwind_c: // Unwind C stack, return from vm_pcall. 494 |->vm_unwind_c: // Unwind C stack, return from vm_pcall.
495 | endbr
486 | // (void *cframe, int errcode) 496 | // (void *cframe, int errcode)
487 | mov eax, CARG2d // Error return status for vm_pcall. 497 | mov eax, CARG2d // Error return status for vm_pcall.
488 | mov rsp, CARG1 498 | mov rsp, CARG1
489 |->vm_unwind_c_eh: // Landing pad for external unwinder. 499 |->vm_unwind_c_eh: // Landing pad for external unwinder.
500 | endbr
490 | mov L:RB, SAVE_L 501 | mov L:RB, SAVE_L
491 | mov GL:RB, L:RB->glref 502 | mov GL:RB, L:RB->glref
492 | mov dword GL:RB->vmstate, ~LJ_VMST_C 503 | mov dword GL:RB->vmstate, ~LJ_VMST_C
493 | jmp ->vm_leave_unw 504 | jmp ->vm_leave_unw
494 | 505 |
495 |->vm_unwind_rethrow: 506 |->vm_unwind_rethrow:
507 | endbr
496 |.if not X64WIN 508 |.if not X64WIN
497 | mov CARG1, SAVE_L 509 | mov CARG1, SAVE_L
498 | mov CARG2d, eax 510 | mov CARG2d, eax
@@ -501,10 +513,12 @@ static void build_subroutines(BuildCtx *ctx)
501 |.endif 513 |.endif
502 | 514 |
503 |->vm_unwind_ff: // Unwind C stack, return from ff pcall. 515 |->vm_unwind_ff: // Unwind C stack, return from ff pcall.
516 | endbr
504 | // (void *cframe) 517 | // (void *cframe)
505 | and CARG1, CFRAME_RAWMASK 518 | and CARG1, CFRAME_RAWMASK
506 | mov rsp, CARG1 519 | mov rsp, CARG1
507 |->vm_unwind_ff_eh: // Landing pad for external unwinder. 520 |->vm_unwind_ff_eh: // Landing pad for external unwinder.
521 | endbr
508 | mov L:RB, SAVE_L 522 | mov L:RB, SAVE_L
509 | mov RDd, 1+1 // Really 1+2 results, incr. later. 523 | mov RDd, 1+1 // Really 1+2 results, incr. later.
510 | mov BASE, L:RB->base 524 | mov BASE, L:RB->base
@@ -675,6 +689,7 @@ static void build_subroutines(BuildCtx *ctx)
675 |//-- Continuation dispatch ---------------------------------------------- 689 |//-- Continuation dispatch ----------------------------------------------
676 | 690 |
677 |->cont_dispatch: 691 |->cont_dispatch:
692 | endbr
678 | // BASE = meta base, RA = resultofs, RD = nresults+1 (also in MULTRES) 693 | // BASE = meta base, RA = resultofs, RD = nresults+1 (also in MULTRES)
679 | add RA, BASE 694 | add RA, BASE
680 | and PC, -8 695 | and PC, -8
@@ -706,6 +721,7 @@ static void build_subroutines(BuildCtx *ctx)
706 |.endif 721 |.endif
707 | 722 |
708 |->cont_cat: // BASE = base, RC = result, RB = mbase 723 |->cont_cat: // BASE = base, RC = result, RB = mbase
724 | endbr
709 | movzx RAd, PC_RB 725 | movzx RAd, PC_RB
710 | sub RB, 32 726 | sub RB, 32
711 | lea RA, [BASE+RA*8] 727 | lea RA, [BASE+RA*8]
@@ -774,6 +790,7 @@ static void build_subroutines(BuildCtx *ctx)
774 | test RC, RC 790 | test RC, RC
775 | jz >3 791 | jz >3
776 |->cont_ra: // BASE = base, RC = result 792 |->cont_ra: // BASE = base, RC = result
793 | endbr
777 | movzx RAd, PC_RA 794 | movzx RAd, PC_RA
778 | mov RB, [RC] 795 | mov RB, [RC]
779 | mov [BASE+RA*8], RB 796 | mov [BASE+RA*8], RB
@@ -851,6 +868,7 @@ static void build_subroutines(BuildCtx *ctx)
851 | mov RB, [BASE+RA*8] 868 | mov RB, [BASE+RA*8]
852 | mov [RC], RB 869 | mov [RC], RB
853 |->cont_nop: // BASE = base, (RC = result) 870 |->cont_nop: // BASE = base, (RC = result)
871 | endbr
854 | ins_next 872 | ins_next
855 | 873 |
856 |3: // Call __newindex metamethod. 874 |3: // Call __newindex metamethod.
@@ -921,6 +939,7 @@ static void build_subroutines(BuildCtx *ctx)
921 | ins_next 939 | ins_next
922 | 940 |
923 |->cont_condt: // BASE = base, RC = result 941 |->cont_condt: // BASE = base, RC = result
942 | endbr
924 | add PC, 4 943 | add PC, 4
925 | mov ITYPE, [RC] 944 | mov ITYPE, [RC]
926 | sar ITYPE, 47 945 | sar ITYPE, 47
@@ -929,6 +948,7 @@ static void build_subroutines(BuildCtx *ctx)
929 | jmp <6 948 | jmp <6
930 | 949 |
931 |->cont_condf: // BASE = base, RC = result 950 |->cont_condf: // BASE = base, RC = result
951 | endbr
932 | mov ITYPE, [RC] 952 | mov ITYPE, [RC]
933 | sar ITYPE, 47 953 | sar ITYPE, 47
934 | cmp ITYPEd, LJ_TISTRUECOND // Branch if result is false. 954 | cmp ITYPEd, LJ_TISTRUECOND // Branch if result is false.
@@ -1132,16 +1152,17 @@ static void build_subroutines(BuildCtx *ctx)
1132 | 1152 |
1133 |.macro .ffunc, name 1153 |.macro .ffunc, name
1134 |->ff_ .. name: 1154 |->ff_ .. name:
1155 | endbr
1135 |.endmacro 1156 |.endmacro
1136 | 1157 |
1137 |.macro .ffunc_1, name 1158 |.macro .ffunc_1, name
1138 |->ff_ .. name: 1159 |->ff_ .. name:
1139 | cmp NARGS:RDd, 1+1; jb ->fff_fallback 1160 | endbr; cmp NARGS:RDd, 1+1; jb ->fff_fallback
1140 |.endmacro 1161 |.endmacro
1141 | 1162 |
1142 |.macro .ffunc_2, name 1163 |.macro .ffunc_2, name
1143 |->ff_ .. name: 1164 |->ff_ .. name:
1144 | cmp NARGS:RDd, 2+1; jb ->fff_fallback 1165 | endbr; cmp NARGS:RDd, 2+1; jb ->fff_fallback
1145 |.endmacro 1166 |.endmacro
1146 | 1167 |
1147 |.macro .ffunc_n, name, op 1168 |.macro .ffunc_n, name, op
@@ -2207,6 +2228,7 @@ static void build_subroutines(BuildCtx *ctx)
2207 | 2228 |
2208 |->vm_record: // Dispatch target for recording phase. 2229 |->vm_record: // Dispatch target for recording phase.
2209 |.if JIT 2230 |.if JIT
2231 | endbr
2210 | movzx RDd, byte [DISPATCH+DISPATCH_GL(hookmask)] 2232 | movzx RDd, byte [DISPATCH+DISPATCH_GL(hookmask)]
2211 | test RDL, HOOK_VMEVENT // No recording while in vmevent. 2233 | test RDL, HOOK_VMEVENT // No recording while in vmevent.
2212 | jnz >5 2234 | jnz >5
@@ -2220,12 +2242,14 @@ static void build_subroutines(BuildCtx *ctx)
2220 |.endif 2242 |.endif
2221 | 2243 |
2222 |->vm_rethook: // Dispatch target for return hooks. 2244 |->vm_rethook: // Dispatch target for return hooks.
2245 | endbr
2223 | movzx RDd, byte [DISPATCH+DISPATCH_GL(hookmask)] 2246 | movzx RDd, byte [DISPATCH+DISPATCH_GL(hookmask)]
2224 | test RDL, HOOK_ACTIVE // Hook already active? 2247 | test RDL, HOOK_ACTIVE // Hook already active?
2225 | jnz >5 2248 | jnz >5
2226 | jmp >1 2249 | jmp >1
2227 | 2250 |
2228 |->vm_inshook: // Dispatch target for instr/line hooks. 2251 |->vm_inshook: // Dispatch target for instr/line hooks.
2252 | endbr
2229 | movzx RDd, byte [DISPATCH+DISPATCH_GL(hookmask)] 2253 | movzx RDd, byte [DISPATCH+DISPATCH_GL(hookmask)]
2230 | test RDL, HOOK_ACTIVE // Hook already active? 2254 | test RDL, HOOK_ACTIVE // Hook already active?
2231 | jnz >5 2255 | jnz >5
@@ -2253,6 +2277,7 @@ static void build_subroutines(BuildCtx *ctx)
2253 | jmp aword [DISPATCH+OP*8+GG_DISP2STATIC] // Re-dispatch to static ins. 2277 | jmp aword [DISPATCH+OP*8+GG_DISP2STATIC] // Re-dispatch to static ins.
2254 | 2278 |
2255 |->cont_hook: // Continue from hook yield. 2279 |->cont_hook: // Continue from hook yield.
2280 | endbr
2256 | add PC, 4 2281 | add PC, 4
2257 | mov RA, [RB-40] 2282 | mov RA, [RB-40]
2258 | mov MULTRES, RAd // Restore MULTRES for *M ins. 2283 | mov MULTRES, RAd // Restore MULTRES for *M ins.
@@ -2277,6 +2302,7 @@ static void build_subroutines(BuildCtx *ctx)
2277 |.endif 2302 |.endif
2278 | 2303 |
2279 |->vm_callhook: // Dispatch target for call hooks. 2304 |->vm_callhook: // Dispatch target for call hooks.
2305 | endbr
2280 | mov SAVE_PC, PC 2306 | mov SAVE_PC, PC
2281 |.if JIT 2307 |.if JIT
2282 | jmp >1 2308 | jmp >1
@@ -2312,6 +2338,7 @@ static void build_subroutines(BuildCtx *ctx)
2312 | 2338 |
2313 |->cont_stitch: // Trace stitching. 2339 |->cont_stitch: // Trace stitching.
2314 |.if JIT 2340 |.if JIT
2341 | endbr
2315 | // BASE = base, RC = result, RB = mbase 2342 | // BASE = base, RC = result, RB = mbase
2316 | mov TRACE:ITYPE, [RB-40] // Save previous trace. 2343 | mov TRACE:ITYPE, [RB-40] // Save previous trace.
2317 | cleartp TRACE:ITYPE 2344 | cleartp TRACE:ITYPE
@@ -2364,6 +2391,7 @@ static void build_subroutines(BuildCtx *ctx)
2364 | 2391 |
2365 |->vm_profhook: // Dispatch target for profiler hook. 2392 |->vm_profhook: // Dispatch target for profiler hook.
2366#if LJ_HASPROFILE 2393#if LJ_HASPROFILE
2394 | endbr
2367 | mov L:RB, SAVE_L 2395 | mov L:RB, SAVE_L
2368 | mov L:RB->base, BASE 2396 | mov L:RB->base, BASE
2369 | mov CARG2, PC // Caveat: CARG2 == BASE 2397 | mov CARG2, PC // Caveat: CARG2 == BASE
@@ -2383,6 +2411,7 @@ static void build_subroutines(BuildCtx *ctx)
2383 |// The 16 bit exit number is stored with two (sign-extended) push imm8. 2411 |// The 16 bit exit number is stored with two (sign-extended) push imm8.
2384 |->vm_exit_handler: 2412 |->vm_exit_handler:
2385 |.if JIT 2413 |.if JIT
2414 | endbr
2386 | push r13; push r12 2415 | push r13; push r12
2387 | push r11; push r10; push r9; push r8 2416 | push r11; push r10; push r9; push r8
2388 | push rdi; push rsi; push rbp; lea rbp, [rsp+88]; push rbp 2417 | push rdi; push rsi; push rbp; lea rbp, [rsp+88]; push rbp
@@ -2431,6 +2460,7 @@ static void build_subroutines(BuildCtx *ctx)
2431 | jmp >1 2460 | jmp >1
2432 |.endif 2461 |.endif
2433 |->vm_exit_interp: 2462 |->vm_exit_interp:
2463 | endbr
2434 | // RD = MULTRES or negated error code, BASE, PC and DISPATCH set. 2464 | // RD = MULTRES or negated error code, BASE, PC and DISPATCH set.
2435 |.if JIT 2465 |.if JIT
2436 | // Restore additional callee-save registers only used in compiled code. 2466 | // Restore additional callee-save registers only used in compiled code.
@@ -2524,6 +2554,7 @@ static void build_subroutines(BuildCtx *ctx)
2524 |.macro vm_round, name, mode, cond 2554 |.macro vm_round, name, mode, cond
2525 |->name: 2555 |->name:
2526 |->name .. _sse: 2556 |->name .. _sse:
2557 | endbr
2527 | sseconst_abs xmm2, RD 2558 | sseconst_abs xmm2, RD
2528 | sseconst_2p52 xmm3, RD 2559 | sseconst_2p52 xmm3, RD
2529 | movaps xmm1, xmm0 2560 | movaps xmm1, xmm0
@@ -2634,6 +2665,7 @@ static void build_subroutines(BuildCtx *ctx)
2634 |// Next idx returned in edx. 2665 |// Next idx returned in edx.
2635 |->vm_next: 2666 |->vm_next:
2636 |.if JIT 2667 |.if JIT
2668 | endbr
2637 | mov NEXT_ASIZE, NEXT_TAB->asize 2669 | mov NEXT_ASIZE, NEXT_TAB->asize
2638 |1: // Traverse array part. 2670 |1: // Traverse array part.
2639 | cmp NEXT_IDX, NEXT_ASIZE; jae >5 2671 | cmp NEXT_IDX, NEXT_ASIZE; jae >5
@@ -4087,6 +4119,7 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop)
4087 4119
4088 case BC_ITERN: 4120 case BC_ITERN:
4089 |.if JIT 4121 |.if JIT
4122 | endbr
4090 | hotloop RBd 4123 | hotloop RBd
4091 |.endif 4124 |.endif
4092 |->vm_IITERN: 4125 |->vm_IITERN:
@@ -4266,6 +4299,7 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop)
4266 | jnz >7 // Not returning to a fixarg Lua func? 4299 | jnz >7 // Not returning to a fixarg Lua func?
4267 switch (op) { 4300 switch (op) {
4268 case BC_RET: 4301 case BC_RET:
4302 | endbr
4269 |->BC_RET_Z: 4303 |->BC_RET_Z:
4270 | mov KBASE, BASE // Use KBASE for result move. 4304 | mov KBASE, BASE // Use KBASE for result move.
4271 | sub RDd, 1 4305 | sub RDd, 1
@@ -4284,10 +4318,12 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop)
4284 | ja >6 4318 | ja >6
4285 break; 4319 break;
4286 case BC_RET1: 4320 case BC_RET1:
4321 | endbr
4287 | mov RB, [BASE+RA] 4322 | mov RB, [BASE+RA]
4288 | mov [BASE-16], RB 4323 | mov [BASE-16], RB
4289 /* fallthrough */ 4324 /* fallthrough */
4290 case BC_RET0: 4325 case BC_RET0:
4326 | endbr
4291 |5: 4327 |5:
4292 | cmp PC_RB, RDL // More results expected? 4328 | cmp PC_RB, RDL // More results expected?
4293 | ja >6 4329 | ja >6
@@ -4334,6 +4370,7 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop)
4334 4370
4335 case BC_FORL: 4371 case BC_FORL:
4336 |.if JIT 4372 |.if JIT
4373 | endbr
4337 | hotloop RBd 4374 | hotloop RBd
4338 |.endif 4375 |.endif
4339 | // Fall through. Assumes BC_IFORL follows and ins_AJ is a no-op. 4376 | // Fall through. Assumes BC_IFORL follows and ins_AJ is a no-op.
@@ -4485,6 +4522,7 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop)
4485 4522
4486 case BC_ITERL: 4523 case BC_ITERL:
4487 |.if JIT 4524 |.if JIT
4525 | endbr
4488 | hotloop RBd 4526 | hotloop RBd
4489 |.endif 4527 |.endif
4490 | // Fall through. Assumes BC_IITERL follows and ins_AJ is a no-op. 4528 | // Fall through. Assumes BC_IITERL follows and ins_AJ is a no-op.
@@ -4578,6 +4616,7 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop)
4578 4616
4579 case BC_FUNCF: 4617 case BC_FUNCF:
4580 |.if JIT 4618 |.if JIT
4619 | endbr
4581 | hotcall RBd 4620 | hotcall RBd
4582 |.endif 4621 |.endif
4583 case BC_FUNCV: /* NYI: compiled vararg functions. */ 4622 case BC_FUNCV: /* NYI: compiled vararg functions. */