aboutsummaryrefslogtreecommitdiff
path: root/src/vm_arm64.dasc
diff options
context:
space:
mode:
authorMike Pall <mike>2025-10-28 04:46:10 +0100
committerMike Pall <mike>2025-10-28 04:46:10 +0100
commit8651ef6df45189ad5ab734275568c9538038fcfa (patch)
tree3609dc160911e3299a4f60b4452d8e52f43c6b17 /src/vm_arm64.dasc
parente34a78acf6b8656874b1c25a12a7cd1813d73af9 (diff)
downloadluajit-8651ef6df45189ad5ab734275568c9538038fcfa.tar.gz
luajit-8651ef6df45189ad5ab734275568c9538038fcfa.tar.bz2
luajit-8651ef6df45189ad5ab734275568c9538038fcfa.zip
ARM64: Add support for ARM BTI.
Note: this is not enabled by default, look for CET in lj_arch.h. Thanks to Yuichiro Naito. #1398
Diffstat (limited to 'src/vm_arm64.dasc')
-rw-r--r--src/vm_arm64.dasc67
1 files changed, 67 insertions, 0 deletions
diff --git a/src/vm_arm64.dasc b/src/vm_arm64.dasc
index 58efe400..85d38de3 100644
--- a/src/vm_arm64.dasc
+++ b/src/vm_arm64.dasc
@@ -92,6 +92,17 @@
92|.macro ret_auth; ret; .endmacro 92|.macro ret_auth; ret; .endmacro
93|.endif 93|.endif
94| 94|
95|// ARM64 branch target identification (BTI).
96|.if BRANCH_TRACK
97|.macro bti_jump; bti j; .endmacro
98|.macro bti_call; bti c; .endmacro
99|.macro bti_tailcall; bti jc; .endmacro
100|.else
101|.macro bti_jump; .endmacro
102|.macro bti_call; .endmacro
103|.macro bti_tailcall; .endmacro
104|.endif
105|
95|//----------------------------------------------------------------------- 106|//-----------------------------------------------------------------------
96| 107|
97|// Stack layout while in interpreter. Must match with lj_frame.h. 108|// Stack layout while in interpreter. Must match with lj_frame.h.
@@ -439,24 +450,28 @@ static void build_subroutines(BuildCtx *ctx)
439 | 450 |
440 |->vm_unwind_c: // Unwind C stack, return from vm_pcall. 451 |->vm_unwind_c: // Unwind C stack, return from vm_pcall.
441 | // (void *cframe, int errcode) 452 | // (void *cframe, int errcode)
453 | bti_tailcall
442 | add fp, CARG1, # SAVE_FP_LR_ 454 | add fp, CARG1, # SAVE_FP_LR_
443 | mov sp, CARG1 455 | mov sp, CARG1
444 | mov CRET1, CARG2 456 | mov CRET1, CARG2
445 | ldr L, SAVE_L 457 | ldr L, SAVE_L
446 | ldr GL, L->glref 458 | ldr GL, L->glref
447 |->vm_unwind_c_eh: // Landing pad for external unwinder. 459 |->vm_unwind_c_eh: // Landing pad for external unwinder.
460 | bti_tailcall
448 | mv_vmstate TMP0w, C 461 | mv_vmstate TMP0w, C
449 | st_vmstate TMP0w 462 | st_vmstate TMP0w
450 | b ->vm_leave_unw 463 | b ->vm_leave_unw
451 | 464 |
452 |->vm_unwind_ff: // Unwind C stack, return from ff pcall. 465 |->vm_unwind_ff: // Unwind C stack, return from ff pcall.
453 | // (void *cframe) 466 | // (void *cframe)
467 | bti_tailcall
454 | add fp, CARG1, # SAVE_FP_LR_ 468 | add fp, CARG1, # SAVE_FP_LR_
455 | mov sp, CARG1 469 | mov sp, CARG1
456 | ldr L, SAVE_L 470 | ldr L, SAVE_L
457 | init_constants 471 | init_constants
458 | ldr GL, L->glref // Setup pointer to global state. 472 | ldr GL, L->glref // Setup pointer to global state.
459 |->vm_unwind_ff_eh: // Landing pad for external unwinder. 473 |->vm_unwind_ff_eh: // Landing pad for external unwinder.
474 | bti_tailcall
460 | mov RC, #16 // 2 results: false + error message. 475 | mov RC, #16 // 2 results: false + error message.
461 | ldr BASE, L->base 476 | ldr BASE, L->base
462 | mov_false TMP0 477 | mov_false TMP0
@@ -632,6 +647,7 @@ static void build_subroutines(BuildCtx *ctx)
632 |.endif 647 |.endif
633 | 648 |
634 |->cont_cat: // RA = resultptr, CARG4 = meta base 649 |->cont_cat: // RA = resultptr, CARG4 = meta base
650 | bti_jump
635 | ldr INSw, [PC, #-4] 651 | ldr INSw, [PC, #-4]
636 | sub CARG2, CARG4, #32 652 | sub CARG2, CARG4, #32
637 | ldr TMP0, [RA] 653 | ldr TMP0, [RA]
@@ -789,9 +805,11 @@ static void build_subroutines(BuildCtx *ctx)
789 | sub RB, RB, #0x20000 805 | sub RB, RB, #0x20000
790 | csel PC, PC, RB, lo 806 | csel PC, PC, RB, lo
791 |->cont_nop: 807 |->cont_nop:
808 | bti_jump
792 | ins_next 809 | ins_next
793 | 810 |
794 |->cont_ra: // RA = resultptr 811 |->cont_ra: // RA = resultptr
812 | bti_jump
795 | ldr INSw, [PC, #-4] 813 | ldr INSw, [PC, #-4]
796 | ldr TMP0, [RA] 814 | ldr TMP0, [RA]
797 | decode_RA TMP1, INS 815 | decode_RA TMP1, INS
@@ -799,12 +817,14 @@ static void build_subroutines(BuildCtx *ctx)
799 | b ->cont_nop 817 | b ->cont_nop
800 | 818 |
801 |->cont_condt: // RA = resultptr 819 |->cont_condt: // RA = resultptr
820 | bti_jump
802 | ldr TMP0, [RA] 821 | ldr TMP0, [RA]
803 | mov_true TMP1 822 | mov_true TMP1
804 | cmp TMP1, TMP0 // Branch if result is true. 823 | cmp TMP1, TMP0 // Branch if result is true.
805 | b <4 824 | b <4
806 | 825 |
807 |->cont_condf: // RA = resultptr 826 |->cont_condf: // RA = resultptr
827 | bti_jump
808 | ldr TMP0, [RA] 828 | ldr TMP0, [RA]
809 | mov_false TMP1 829 | mov_false TMP1
810 | cmp TMP0, TMP1 // Branch if result is false. 830 | cmp TMP0, TMP1 // Branch if result is false.
@@ -956,10 +976,12 @@ static void build_subroutines(BuildCtx *ctx)
956 | 976 |
957 |.macro .ffunc, name 977 |.macro .ffunc, name
958 |->ff_ .. name: 978 |->ff_ .. name:
979 | bti_jump
959 |.endmacro 980 |.endmacro
960 | 981 |
961 |.macro .ffunc_1, name 982 |.macro .ffunc_1, name
962 |->ff_ .. name: 983 |->ff_ .. name:
984 | bti_jump
963 | ldr CARG1, [BASE] 985 | ldr CARG1, [BASE]
964 | cmp NARGS8:RC, #8 986 | cmp NARGS8:RC, #8
965 | blo ->fff_fallback 987 | blo ->fff_fallback
@@ -967,6 +989,7 @@ static void build_subroutines(BuildCtx *ctx)
967 | 989 |
968 |.macro .ffunc_2, name 990 |.macro .ffunc_2, name
969 |->ff_ .. name: 991 |->ff_ .. name:
992 | bti_jump
970 | ldp CARG1, CARG2, [BASE] 993 | ldp CARG1, CARG2, [BASE]
971 | cmp NARGS8:RC, #16 994 | cmp NARGS8:RC, #16
972 | blo ->fff_fallback 995 | blo ->fff_fallback
@@ -1810,6 +1833,7 @@ static void build_subroutines(BuildCtx *ctx)
1810 | 1833 |
1811 |->vm_record: // Dispatch target for recording phase. 1834 |->vm_record: // Dispatch target for recording phase.
1812 |.if JIT 1835 |.if JIT
1836 | bti_jump
1813 | ldrb CARG1w, GL->hookmask 1837 | ldrb CARG1w, GL->hookmask
1814 | tst CARG1, #HOOK_VMEVENT // No recording while in vmevent. 1838 | tst CARG1, #HOOK_VMEVENT // No recording while in vmevent.
1815 | bne >5 1839 | bne >5
@@ -1825,6 +1849,7 @@ static void build_subroutines(BuildCtx *ctx)
1825 |.endif 1849 |.endif
1826 | 1850 |
1827 |->vm_rethook: // Dispatch target for return hooks. 1851 |->vm_rethook: // Dispatch target for return hooks.
1852 | bti_jump
1828 | ldrb TMP2w, GL->hookmask 1853 | ldrb TMP2w, GL->hookmask
1829 | tbz TMP2w, #HOOK_ACTIVE_SHIFT, >1 // Hook already active? 1854 | tbz TMP2w, #HOOK_ACTIVE_SHIFT, >1 // Hook already active?
1830 |5: // Re-dispatch to static ins. 1855 |5: // Re-dispatch to static ins.
@@ -1832,6 +1857,7 @@ static void build_subroutines(BuildCtx *ctx)
1832 | br_auth TMP0 1857 | br_auth TMP0
1833 | 1858 |
1834 |->vm_inshook: // Dispatch target for instr/line hooks. 1859 |->vm_inshook: // Dispatch target for instr/line hooks.
1860 | bti_jump
1835 | ldrb TMP2w, GL->hookmask 1861 | ldrb TMP2w, GL->hookmask
1836 | ldr TMP3w, GL->hookcount 1862 | ldr TMP3w, GL->hookcount
1837 | tbnz TMP2w, #HOOK_ACTIVE_SHIFT, <5 // Hook already active? 1863 | tbnz TMP2w, #HOOK_ACTIVE_SHIFT, <5 // Hook already active?
@@ -1858,6 +1884,7 @@ static void build_subroutines(BuildCtx *ctx)
1858 | br_auth TMP0 1884 | br_auth TMP0
1859 | 1885 |
1860 |->cont_hook: // Continue from hook yield. 1886 |->cont_hook: // Continue from hook yield.
1887 | bti_jump
1861 | ldr CARG1, [CARG4, #-40] 1888 | ldr CARG1, [CARG4, #-40]
1862 | add PC, PC, #4 1889 | add PC, PC, #4
1863 | str CARG1w, SAVE_MULTRES // Restore MULTRES for *M ins. 1890 | str CARG1w, SAVE_MULTRES // Restore MULTRES for *M ins.
@@ -1881,6 +1908,7 @@ static void build_subroutines(BuildCtx *ctx)
1881 |.endif 1908 |.endif
1882 | 1909 |
1883 |->vm_callhook: // Dispatch target for call hooks. 1910 |->vm_callhook: // Dispatch target for call hooks.
1911 | bti_jump
1884 | mov CARG2, PC 1912 | mov CARG2, PC
1885 |.if JIT 1913 |.if JIT
1886 | b >1 1914 | b >1
@@ -1910,6 +1938,7 @@ static void build_subroutines(BuildCtx *ctx)
1910 |->cont_stitch: // Trace stitching. 1938 |->cont_stitch: // Trace stitching.
1911 |.if JIT 1939 |.if JIT
1912 | // RA = resultptr, CARG4 = meta base 1940 | // RA = resultptr, CARG4 = meta base
1941 | bti_jump
1913 | ldr RBw, SAVE_MULTRES 1942 | ldr RBw, SAVE_MULTRES
1914 | ldr INSw, [PC, #-4] 1943 | ldr INSw, [PC, #-4]
1915 | ldr TRACE:CARG3, [CARG4, #-40] // Save previous trace. 1944 | ldr TRACE:CARG3, [CARG4, #-40] // Save previous trace.
@@ -1958,6 +1987,7 @@ static void build_subroutines(BuildCtx *ctx)
1958 | 1987 |
1959 |->vm_profhook: // Dispatch target for profiler hook. 1988 |->vm_profhook: // Dispatch target for profiler hook.
1960#if LJ_HASPROFILE 1989#if LJ_HASPROFILE
1990 | bti_jump
1961 | mov CARG1, L 1991 | mov CARG1, L
1962 | str BASE, L->base 1992 | str BASE, L->base
1963 | mov CARG2, PC 1993 | mov CARG2, PC
@@ -1979,6 +2009,7 @@ static void build_subroutines(BuildCtx *ctx)
1979 | 2009 |
1980 |->vm_exit_handler: 2010 |->vm_exit_handler:
1981 |.if JIT 2011 |.if JIT
2012 | bti_call
1982 | sub sp, sp, #(64*8) 2013 | sub sp, sp, #(64*8)
1983 | savex_, 0, 1 2014 | savex_, 0, 1
1984 | savex_, 2, 3 2015 | savex_, 2, 3
@@ -2029,6 +2060,7 @@ static void build_subroutines(BuildCtx *ctx)
2029 |.endif 2060 |.endif
2030 | 2061 |
2031 |->vm_exit_interp: 2062 |->vm_exit_interp:
2063 | bti_jump
2032 | // CARG1 = MULTRES or negated error code, BASE, PC and GL set. 2064 | // CARG1 = MULTRES or negated error code, BASE, PC and GL set.
2033 |.if JIT 2065 |.if JIT
2034 | ldr L, SAVE_L 2066 | ldr L, SAVE_L
@@ -2106,6 +2138,7 @@ static void build_subroutines(BuildCtx *ctx)
2106 | 2138 |
2107 | // int lj_vm_modi(int dividend, int divisor); 2139 | // int lj_vm_modi(int dividend, int divisor);
2108 |->vm_modi: 2140 |->vm_modi:
2141 | bti_call
2109 | eor CARG4w, CARG1w, CARG2w 2142 | eor CARG4w, CARG1w, CARG2w
2110 | cmp CARG4w, #0 2143 | cmp CARG4w, #0
2111 | eor CARG3w, CARG1w, CARG1w, asr #31 2144 | eor CARG3w, CARG1w, CARG1w, asr #31
@@ -2142,6 +2175,7 @@ static void build_subroutines(BuildCtx *ctx)
2142 |// Next idx returned in CRET2w. 2175 |// Next idx returned in CRET2w.
2143 |->vm_next: 2176 |->vm_next:
2144 |.if JIT 2177 |.if JIT
2178 | bti_call
2145 | ldr NEXT_LIM, NEXT_TAB->asize 2179 | ldr NEXT_LIM, NEXT_TAB->asize
2146 | ldr NEXT_TMP1, NEXT_TAB->array 2180 | ldr NEXT_TMP1, NEXT_TAB->array
2147 |1: // Traverse array part. 2181 |1: // Traverse array part.
@@ -2286,6 +2320,26 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop)
2286 |=>defop: 2320 |=>defop:
2287 2321
2288 switch (op) { 2322 switch (op) {
2323#if !LJ_HASJIT
2324 case BC_FORL:
2325 case BC_JFORI:
2326 case BC_JFORL:
2327 case BC_ITERL:
2328 case BC_JITERL:
2329 case BC_LOOP:
2330 case BC_JLOOP:
2331 case BC_FUNCF:
2332 case BC_JFUNCF:
2333 case BC_JFUNCV:
2334#endif
2335 case BC_FUNCV: /* NYI: compiled vararg functions. */
2336 break; /* Avoid redundant bti instructions. */
2337 default:
2338 | bti_jump
2339 break;
2340 }
2341
2342 switch (op) {
2289 2343
2290 /* -- Comparison ops ---------------------------------------------------- */ 2344 /* -- Comparison ops ---------------------------------------------------- */
2291 2345
@@ -4123,6 +4177,19 @@ static void emit_asm_debug(BuildCtx *ctx)
4123 ".LEFDE3:\n\n", (int)ctx->codesz - fcofs); 4177 ".LEFDE3:\n\n", (int)ctx->codesz - fcofs);
4124#endif 4178#endif
4125#endif 4179#endif
4180#if LJ_TARGET_LINUX && LJ_ABI_BRANCH_TRACK
4181 fprintf(ctx->fp,
4182 "\t.section .note.gnu.property,\"a\"\n"
4183 "\t.align 3\n"
4184 "\t.long 4\n"
4185 "\t.long 16\n"
4186 "\t.long 5\n"
4187 "\t.long 0x00554e47\n"
4188 "\t.long 0xc0000000\n"
4189 "\t.long 4\n"
4190 "\t.long 1\n"
4191 "\t.long 0\n");
4192#endif
4126 break; 4193 break;
4127#if !LJ_NO_UNWIND 4194#if !LJ_NO_UNWIND
4128 case BUILD_machasm: { 4195 case BUILD_machasm: {