aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/jit/dis_arm64.lua8
-rw-r--r--src/lj_arch.h5
-rw-r--r--src/lj_ccallback.c14
-rw-r--r--src/lj_emit_arm64.h7
-rw-r--r--src/lj_target_arm64.h4
-rw-r--r--src/vm_arm64.dasc67
6 files changed, 102 insertions, 3 deletions
diff --git a/src/jit/dis_arm64.lua b/src/jit/dis_arm64.lua
index 4457aac0..944f1a6c 100644
--- a/src/jit/dis_arm64.lua
+++ b/src/jit/dis_arm64.lua
@@ -695,7 +695,10 @@ local map_br = { -- Branches, exception generating and system instructions.
695 }, 695 },
696 { -- System instructions. 696 { -- System instructions.
697 shift = 0, mask = 0x3fffff, 697 shift = 0, mask = 0x3fffff,
698 [0x03201f] = "nop" 698 [0x03201f] = "nop",
699 [0x03245f] = "bti c",
700 [0x03249f] = "bti j",
701 [0x0324df] = "bti jc",
699 }, 702 },
700 { -- Unconditional branch, register. 703 { -- Unconditional branch, register.
701 shift = 0, mask = 0xfffc1f, 704 shift = 0, mask = 0xfffc1f,
@@ -1171,6 +1174,9 @@ local function disass_ins(ctx)
1171 end 1174 end
1172 end 1175 end
1173 second0 = true 1176 second0 = true
1177 elseif p == " " then
1178 operands[#operands+1] = pat:match(" (.*)")
1179 break
1174 else 1180 else
1175 assert(false) 1181 assert(false)
1176 end 1182 end
diff --git a/src/lj_arch.h b/src/lj_arch.h
index a775b51f..6d1a9271 100644
--- a/src/lj_arch.h
+++ b/src/lj_arch.h
@@ -288,6 +288,11 @@
288#if !defined(LJ_ABI_PAUTH) && defined(__arm64e__) 288#if !defined(LJ_ABI_PAUTH) && defined(__arm64e__)
289#define LJ_ABI_PAUTH 1 289#define LJ_ABI_PAUTH 1
290#endif 290#endif
291#if !defined(LJ_ABI_BRANCH_TRACK) && (__ARM_FEATURE_BTI_DEFAULT & 1) && \
292 defined(LUAJIT_ENABLE_CET_BR)
293/* See comments about LUAJIT_ENABLE_CET_BR above. */
294#define LJ_ABI_BRANCH_TRACK 1
295#endif
291#define LJ_TARGET_ARM64 1 296#define LJ_TARGET_ARM64 1
292#define LJ_TARGET_EHRETREG 0 297#define LJ_TARGET_EHRETREG 0
293#define LJ_TARGET_EHRAREG 30 298#define LJ_TARGET_EHRAREG 30
diff --git a/src/lj_ccallback.c b/src/lj_ccallback.c
index 5594a731..c4b25cd7 100644
--- a/src/lj_ccallback.c
+++ b/src/lj_ccallback.c
@@ -64,6 +64,10 @@ static MSize CALLBACK_OFS2SLOT(MSize ofs)
64 64
65#elif LJ_TARGET_ARM64 65#elif LJ_TARGET_ARM64
66 66
67#if LJ_ABI_BRANCH_TRACK
68#define CALLBACK_MCODE_SLOTSZ 12
69#endif
70
67#define CALLBACK_MCODE_HEAD 32 71#define CALLBACK_MCODE_HEAD 32
68 72
69#elif LJ_TARGET_PPC 73#elif LJ_TARGET_PPC
@@ -88,8 +92,11 @@ static MSize CALLBACK_OFS2SLOT(MSize ofs)
88#endif 92#endif
89 93
90#ifndef CALLBACK_SLOT2OFS 94#ifndef CALLBACK_SLOT2OFS
91#define CALLBACK_SLOT2OFS(slot) (CALLBACK_MCODE_HEAD + 8*(slot)) 95#ifndef CALLBACK_MCODE_SLOTSZ
92#define CALLBACK_OFS2SLOT(ofs) (((ofs)-CALLBACK_MCODE_HEAD)/8) 96#define CALLBACK_MCODE_SLOTSZ 8
97#endif
98#define CALLBACK_SLOT2OFS(slot) (CALLBACK_MCODE_HEAD + CALLBACK_MCODE_SLOTSZ*(slot))
99#define CALLBACK_OFS2SLOT(ofs) (((ofs)-CALLBACK_MCODE_HEAD)/CALLBACK_MCODE_SLOTSZ)
93#define CALLBACK_MAX_SLOT (CALLBACK_OFS2SLOT(CALLBACK_MCODE_SIZE)) 100#define CALLBACK_MAX_SLOT (CALLBACK_OFS2SLOT(CALLBACK_MCODE_SIZE))
94#endif 101#endif
95 102
@@ -193,6 +200,9 @@ static void *callback_mcode_init(global_State *g, uint32_t *page)
193 ((void **)p)[1] = g; 200 ((void **)p)[1] = g;
194 p += 4; 201 p += 4;
195 for (slot = 0; slot < CALLBACK_MAX_SLOT; slot++) { 202 for (slot = 0; slot < CALLBACK_MAX_SLOT; slot++) {
203#if LJ_ABI_BRANCH_TRACK
204 *p++ = A64I_BTI_C;
205#endif
196 *p++ = A64I_LE(A64I_MOVZw | A64F_D(RID_X9) | A64F_U16(slot)); 206 *p++ = A64I_LE(A64I_MOVZw | A64F_D(RID_X9) | A64F_U16(slot));
197 *p = A64I_LE(A64I_B | A64F_S26((page-p) & 0x03ffffffu)); 207 *p = A64I_LE(A64I_B | A64F_S26((page-p) & 0x03ffffffu));
198 p++; 208 p++;
diff --git a/src/lj_emit_arm64.h b/src/lj_emit_arm64.h
index ca1269b7..a8be7415 100644
--- a/src/lj_emit_arm64.h
+++ b/src/lj_emit_arm64.h
@@ -409,6 +409,13 @@ static void emit_call(ASMState *as, ASMFunction target)
409 } 409 }
410} 410}
411 411
412#if LJ_ABI_BRANCH_TRACK
413static void emit_branch_track(ASMState *as)
414{
415 *--as->mcp = A64I_BTI_J;
416}
417#endif
418
412/* -- Emit generic operations --------------------------------------------- */ 419/* -- Emit generic operations --------------------------------------------- */
413 420
414/* Generic move between two regs. */ 421/* Generic move between two regs. */
diff --git a/src/lj_target_arm64.h b/src/lj_target_arm64.h
index 92741871..30aff478 100644
--- a/src/lj_target_arm64.h
+++ b/src/lj_target_arm64.h
@@ -265,6 +265,10 @@ typedef enum A64Ins {
265 A64I_BRAAZ = 0xd61f081f, 265 A64I_BRAAZ = 0xd61f081f,
266 A64I_BLRAAZ = 0xd63f081f, 266 A64I_BLRAAZ = 0xd63f081f,
267 267
268 A64I_BTI_C = 0xd503245f,
269 A64I_BTI_J = 0xd503249f,
270 A64I_BTI_JC = 0xd50324df,
271
268 A64I_NOP = 0xd503201f, 272 A64I_NOP = 0xd503201f,
269 273
270 /* FP */ 274 /* FP */
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: {