diff options
| author | Mike Pall <mike> | 2025-10-28 04:46:10 +0100 |
|---|---|---|
| committer | Mike Pall <mike> | 2025-10-28 04:46:10 +0100 |
| commit | 8651ef6df45189ad5ab734275568c9538038fcfa (patch) | |
| tree | 3609dc160911e3299a4f60b4452d8e52f43c6b17 | |
| parent | e34a78acf6b8656874b1c25a12a7cd1813d73af9 (diff) | |
| download | luajit-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
| -rw-r--r-- | dynasm/dasm_arm64.lua | 22 | ||||
| -rw-r--r-- | src/jit/dis_arm64.lua | 8 | ||||
| -rw-r--r-- | src/lj_arch.h | 5 | ||||
| -rw-r--r-- | src/lj_ccallback.c | 14 | ||||
| -rw-r--r-- | src/lj_emit_arm64.h | 7 | ||||
| -rw-r--r-- | src/lj_target_arm64.h | 4 | ||||
| -rw-r--r-- | src/vm_arm64.dasc | 67 |
7 files changed, 124 insertions, 3 deletions
diff --git a/dynasm/dasm_arm64.lua b/dynasm/dasm_arm64.lua index 8b27e962..db3adb48 100644 --- a/dynasm/dasm_arm64.lua +++ b/dynasm/dasm_arm64.lua | |||
| @@ -244,6 +244,10 @@ local map_cond = { | |||
| 244 | hs = 2, lo = 3, | 244 | hs = 2, lo = 3, |
| 245 | } | 245 | } |
| 246 | 246 | ||
| 247 | local map_bti = { | ||
| 248 | c = 0x40, j = 0x80, jc = 0xc0, | ||
| 249 | } | ||
| 250 | |||
| 247 | ------------------------------------------------------------------------------ | 251 | ------------------------------------------------------------------------------ |
| 248 | 252 | ||
| 249 | local parse_reg_type | 253 | local parse_reg_type |
| @@ -475,6 +479,12 @@ local function parse_cond(expr, inv) | |||
| 475 | return shl(bit.bxor(c, inv), 12) | 479 | return shl(bit.bxor(c, inv), 12) |
| 476 | end | 480 | end |
| 477 | 481 | ||
| 482 | local function parse_map(expr, map) | ||
| 483 | local x = map[expr] | ||
| 484 | if not x then werror("bad operand") end | ||
| 485 | return x | ||
| 486 | end | ||
| 487 | |||
| 478 | local function parse_load(params, nparams, n, op) | 488 | local function parse_load(params, nparams, n, op) |
| 479 | if params[n+2] then werror("too many operands") end | 489 | if params[n+2] then werror("too many operands") end |
| 480 | local scale = shr(op, 30) | 490 | local scale = shr(op, 30) |
| @@ -823,11 +833,21 @@ map_op = { | |||
| 823 | tbz_3 = "36000000DTBw|36000000DTBx", | 833 | tbz_3 = "36000000DTBw|36000000DTBx", |
| 824 | tbnz_3 = "37000000DTBw|37000000DTBx", | 834 | tbnz_3 = "37000000DTBw|37000000DTBx", |
| 825 | 835 | ||
| 836 | -- Branch Target Identification. | ||
| 837 | bti_1 = "d503241ft", | ||
| 838 | |||
| 826 | -- ARM64e: Pointer authentication codes (PAC). | 839 | -- ARM64e: Pointer authentication codes (PAC). |
| 827 | blraaz_1 = "d63f081fNx", | 840 | blraaz_1 = "d63f081fNx", |
| 841 | blrabz_1 = "d63f0c1fNx", | ||
| 828 | braa_2 = "d71f0800NDx", | 842 | braa_2 = "d71f0800NDx", |
| 843 | brab_2 = "d71f0c00NDx", | ||
| 829 | braaz_1 = "d61f081fNx", | 844 | braaz_1 = "d61f081fNx", |
| 845 | brabz_1 = "d61f0c1fNx", | ||
| 846 | paciasp_0 = "d503233f", | ||
| 830 | pacibsp_0 = "d503237f", | 847 | pacibsp_0 = "d503237f", |
| 848 | autiasp_0 = "d50323bf", | ||
| 849 | autibsp_0 = "d50323ff", | ||
| 850 | retaa_0 = "d65f0bff", | ||
| 831 | retab_0 = "d65f0fff", | 851 | retab_0 = "d65f0fff", |
| 832 | 852 | ||
| 833 | -- Miscellaneous instructions. | 853 | -- Miscellaneous instructions. |
| @@ -996,6 +1016,8 @@ local function parse_template(params, template, nparams, pos) | |||
| 996 | op = op + parse_cond(q, 0); n = n + 1 | 1016 | op = op + parse_cond(q, 0); n = n + 1 |
| 997 | elseif p == "c" then | 1017 | elseif p == "c" then |
| 998 | op = op + parse_cond(q, 1); n = n + 1 | 1018 | op = op + parse_cond(q, 1); n = n + 1 |
| 1019 | elseif p == "t" then | ||
| 1020 | op = op + parse_map(q, map_bti); n = n + 1 | ||
| 999 | 1021 | ||
| 1000 | else | 1022 | else |
| 1001 | assert(false) | 1023 | assert(false) |
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 | ||
| 413 | static 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: { |
