diff options
| author | Mike Pall <mike> | 2023-08-12 22:25:40 +0200 |
|---|---|---|
| committer | Mike Pall <mike> | 2023-08-12 22:25:40 +0200 |
| commit | 27af72e66f6a285298d1a9be370779aae945eb14 (patch) | |
| tree | 5b12777dac86ab8afbdfd337af020f1d1da0f044 /src | |
| parent | 117ddf35e6ef1bb9016881f828337677db493cee (diff) | |
| download | luajit-27af72e66f6a285298d1a9be370779aae945eb14.tar.gz luajit-27af72e66f6a285298d1a9be370779aae945eb14.tar.bz2 luajit-27af72e66f6a285298d1a9be370779aae945eb14.zip | |
ARM64: Add support for ARM64e pointer authentication codes (PAC).
Contributed by Peter Cawley. #559
Diffstat (limited to 'src')
| -rw-r--r-- | src/Makefile | 4 | ||||
| -rw-r--r-- | src/lib_ffi.c | 3 | ||||
| -rw-r--r-- | src/lib_jit.c | 3 | ||||
| -rw-r--r-- | src/lj_arch.h | 7 | ||||
| -rw-r--r-- | src/lj_asm_arm64.h | 6 | ||||
| -rw-r--r-- | src/lj_ccallback.c | 6 | ||||
| -rw-r--r-- | src/lj_emit_arm64.h | 12 | ||||
| -rw-r--r-- | src/lj_err.c | 18 | ||||
| -rw-r--r-- | src/lj_jit.h | 3 | ||||
| -rw-r--r-- | src/lj_obj.h | 14 | ||||
| -rw-r--r-- | src/lj_target_arm64.h | 6 | ||||
| -rw-r--r-- | src/lj_trace.c | 3 | ||||
| -rw-r--r-- | src/lj_vm.h | 6 | ||||
| -rw-r--r-- | src/vm_arm64.dasc | 56 |
14 files changed, 115 insertions, 32 deletions
diff --git a/src/Makefile b/src/Makefile index 30d64be2..f6d093bb 100644 --- a/src/Makefile +++ b/src/Makefile | |||
| @@ -433,6 +433,10 @@ ifneq (,$(findstring LJ_NO_UNWIND 1,$(TARGET_TESTARCH))) | |||
| 433 | DASM_AFLAGS+= -D NO_UNWIND | 433 | DASM_AFLAGS+= -D NO_UNWIND |
| 434 | TARGET_ARCH+= -DLUAJIT_NO_UNWIND | 434 | TARGET_ARCH+= -DLUAJIT_NO_UNWIND |
| 435 | endif | 435 | endif |
| 436 | ifneq (,$(findstring LJ_ABI_PAUTH 1,$(TARGET_TESTARCH))) | ||
| 437 | DASM_AFLAGS+= -D PAUTH | ||
| 438 | TARGET_ARCH+= -DLJ_ABI_PAUTH=1 | ||
| 439 | endif | ||
| 436 | DASM_AFLAGS+= -D VER=$(subst LJ_ARCH_VERSION_,,$(filter LJ_ARCH_VERSION_%,$(subst LJ_ARCH_VERSION ,LJ_ARCH_VERSION_,$(TARGET_TESTARCH)))) | 440 | DASM_AFLAGS+= -D VER=$(subst LJ_ARCH_VERSION_,,$(filter LJ_ARCH_VERSION_%,$(subst LJ_ARCH_VERSION ,LJ_ARCH_VERSION_,$(TARGET_TESTARCH)))) |
| 437 | ifeq (Windows,$(TARGET_SYS)) | 441 | ifeq (Windows,$(TARGET_SYS)) |
| 438 | DASM_AFLAGS+= -D WIN | 442 | DASM_AFLAGS+= -D WIN |
diff --git a/src/lib_ffi.c b/src/lib_ffi.c index 1b1fa389..3133cab2 100644 --- a/src/lib_ffi.c +++ b/src/lib_ffi.c | |||
| @@ -745,6 +745,9 @@ LJLIB_CF(ffi_abi) LJLIB_REC(.) | |||
| 745 | #if LJ_ABI_WIN | 745 | #if LJ_ABI_WIN |
| 746 | "\003win" | 746 | "\003win" |
| 747 | #endif | 747 | #endif |
| 748 | #if LJ_ABI_PAUTH | ||
| 749 | "\007pauth" | ||
| 750 | #endif | ||
| 748 | #if LJ_TARGET_UWP | 751 | #if LJ_TARGET_UWP |
| 749 | "\003uwp" | 752 | "\003uwp" |
| 750 | #endif | 753 | #endif |
diff --git a/src/lib_jit.c b/src/lib_jit.c index 2867d420..2300f1da 100644 --- a/src/lib_jit.c +++ b/src/lib_jit.c | |||
| @@ -422,7 +422,8 @@ LJLIB_CF(jit_util_ircalladdr) | |||
| 422 | { | 422 | { |
| 423 | uint32_t idx = (uint32_t)lj_lib_checkint(L, 1); | 423 | uint32_t idx = (uint32_t)lj_lib_checkint(L, 1); |
| 424 | if (idx < IRCALL__MAX) { | 424 | if (idx < IRCALL__MAX) { |
| 425 | setintptrV(L->top-1, (intptr_t)(void *)lj_ir_callinfo[idx].func); | 425 | ASMFunction func = lj_ir_callinfo[idx].func; |
| 426 | setintptrV(L->top-1, (intptr_t)(void *)lj_ptr_strip(func)); | ||
| 426 | return 1; | 427 | return 1; |
| 427 | } | 428 | } |
| 428 | return 0; | 429 | return 0; |
diff --git a/src/lj_arch.h b/src/lj_arch.h index bddd757d..d354fc69 100644 --- a/src/lj_arch.h +++ b/src/lj_arch.h | |||
| @@ -259,6 +259,9 @@ | |||
| 259 | #define LJ_ARCH_NAME "arm64" | 259 | #define LJ_ARCH_NAME "arm64" |
| 260 | #define LJ_ARCH_ENDIAN LUAJIT_LE | 260 | #define LJ_ARCH_ENDIAN LUAJIT_LE |
| 261 | #endif | 261 | #endif |
| 262 | #if !defined(LJ_ABI_PAUTH) && defined(__arm64e__) | ||
| 263 | #define LJ_ABI_PAUTH 1 | ||
| 264 | #endif | ||
| 262 | #define LJ_TARGET_ARM64 1 | 265 | #define LJ_TARGET_ARM64 1 |
| 263 | #define LJ_TARGET_EHRETREG 0 | 266 | #define LJ_TARGET_EHRETREG 0 |
| 264 | #define LJ_TARGET_EHRAREG 30 | 267 | #define LJ_TARGET_EHRAREG 30 |
| @@ -603,6 +606,10 @@ | |||
| 603 | #define LJ_SOFTFP (!LJ_ARCH_HASFPU) | 606 | #define LJ_SOFTFP (!LJ_ARCH_HASFPU) |
| 604 | #define LJ_SOFTFP32 (LJ_SOFTFP && LJ_32) | 607 | #define LJ_SOFTFP32 (LJ_SOFTFP && LJ_32) |
| 605 | 608 | ||
| 609 | #ifndef LJ_ABI_PAUTH | ||
| 610 | #define LJ_ABI_PAUTH 0 | ||
| 611 | #endif | ||
| 612 | |||
| 606 | #if LJ_ARCH_ENDIAN == LUAJIT_BE | 613 | #if LJ_ARCH_ENDIAN == LUAJIT_BE |
| 607 | #define LJ_LE 0 | 614 | #define LJ_LE 0 |
| 608 | #define LJ_BE 1 | 615 | #define LJ_BE 1 |
diff --git a/src/lj_asm_arm64.h b/src/lj_asm_arm64.h index f761525f..c537c514 100644 --- a/src/lj_asm_arm64.h +++ b/src/lj_asm_arm64.h | |||
| @@ -421,8 +421,8 @@ static void asm_gencall(ASMState *as, const CCallInfo *ci, IRRef *args) | |||
| 421 | uint32_t n, nargs = CCI_XNARGS(ci); | 421 | uint32_t n, nargs = CCI_XNARGS(ci); |
| 422 | int32_t ofs = 0; | 422 | int32_t ofs = 0; |
| 423 | Reg gpr, fpr = REGARG_FIRSTFPR; | 423 | Reg gpr, fpr = REGARG_FIRSTFPR; |
| 424 | if ((void *)ci->func) | 424 | if (ci->func) |
| 425 | emit_call(as, (void *)ci->func); | 425 | emit_call(as, ci->func); |
| 426 | for (gpr = REGARG_FIRSTGPR; gpr <= REGARG_LASTGPR; gpr++) | 426 | for (gpr = REGARG_FIRSTGPR; gpr <= REGARG_LASTGPR; gpr++) |
| 427 | as->cost[gpr] = REGCOST(~0u, ASMREF_L); | 427 | as->cost[gpr] = REGCOST(~0u, ASMREF_L); |
| 428 | gpr = REGARG_FIRSTGPR; | 428 | gpr = REGARG_FIRSTGPR; |
| @@ -501,7 +501,7 @@ static void asm_callx(ASMState *as, IRIns *ir) | |||
| 501 | ci.func = (ASMFunction)(ir_k64(irf)->u64); | 501 | ci.func = (ASMFunction)(ir_k64(irf)->u64); |
| 502 | } else { /* Need a non-argument register for indirect calls. */ | 502 | } else { /* Need a non-argument register for indirect calls. */ |
| 503 | Reg freg = ra_alloc1(as, func, RSET_RANGE(RID_X8, RID_MAX_GPR)-RSET_FIXED); | 503 | Reg freg = ra_alloc1(as, func, RSET_RANGE(RID_X8, RID_MAX_GPR)-RSET_FIXED); |
| 504 | emit_n(as, A64I_BLR, freg); | 504 | emit_n(as, A64I_BLR_AUTH, freg); |
| 505 | ci.func = (ASMFunction)(void *)0; | 505 | ci.func = (ASMFunction)(void *)0; |
| 506 | } | 506 | } |
| 507 | asm_gencall(as, &ci, args); | 507 | asm_gencall(as, &ci, args); |
diff --git a/src/lj_ccallback.c b/src/lj_ccallback.c index 43e44305..98e9e02b 100644 --- a/src/lj_ccallback.c +++ b/src/lj_ccallback.c | |||
| @@ -171,13 +171,13 @@ static void *callback_mcode_init(global_State *g, uint32_t *page) | |||
| 171 | static void *callback_mcode_init(global_State *g, uint32_t *page) | 171 | static void *callback_mcode_init(global_State *g, uint32_t *page) |
| 172 | { | 172 | { |
| 173 | uint32_t *p = page; | 173 | uint32_t *p = page; |
| 174 | void *target = (void *)lj_vm_ffi_callback; | 174 | ASMFunction target = lj_vm_ffi_callback; |
| 175 | MSize slot; | 175 | MSize slot; |
| 176 | *p++ = A64I_LE(A64I_LDRLx | A64F_D(RID_X11) | A64F_S19(4)); | 176 | *p++ = A64I_LE(A64I_LDRLx | A64F_D(RID_X11) | A64F_S19(4)); |
| 177 | *p++ = A64I_LE(A64I_LDRLx | A64F_D(RID_X10) | A64F_S19(5)); | 177 | *p++ = A64I_LE(A64I_LDRLx | A64F_D(RID_X10) | A64F_S19(5)); |
| 178 | *p++ = A64I_LE(A64I_BR | A64F_N(RID_X11)); | 178 | *p++ = A64I_LE(A64I_BR_AUTH | A64F_N(RID_X11)); |
| 179 | *p++ = A64I_LE(A64I_NOP); | 179 | *p++ = A64I_LE(A64I_NOP); |
| 180 | ((void **)p)[0] = target; | 180 | ((ASMFunction *)p)[0] = target; |
| 181 | ((void **)p)[1] = g; | 181 | ((void **)p)[1] = g; |
| 182 | p += 4; | 182 | p += 4; |
| 183 | for (slot = 0; slot < CALLBACK_MAX_SLOT; slot++) { | 183 | for (slot = 0; slot < CALLBACK_MAX_SLOT; slot++) { |
diff --git a/src/lj_emit_arm64.h b/src/lj_emit_arm64.h index fcc9c1d8..65463a5e 100644 --- a/src/lj_emit_arm64.h +++ b/src/lj_emit_arm64.h | |||
| @@ -348,16 +348,22 @@ static void emit_cnb(ASMState *as, A64Ins ai, Reg r, MCode *target) | |||
| 348 | 348 | ||
| 349 | #define emit_jmp(as, target) emit_branch(as, A64I_B, (target)) | 349 | #define emit_jmp(as, target) emit_branch(as, A64I_B, (target)) |
| 350 | 350 | ||
| 351 | static void emit_call(ASMState *as, void *target) | 351 | static void emit_call(ASMState *as, ASMFunction target) |
| 352 | { | 352 | { |
| 353 | MCode *p = --as->mcp; | 353 | MCode *p = --as->mcp; |
| 354 | ptrdiff_t delta = (char *)target - (char *)p; | 354 | #if LJ_ABI_PAUTH |
| 355 | char *targetp = ptrauth_auth_data((char *)target, | ||
| 356 | ptrauth_key_function_pointer, 0); | ||
| 357 | #else | ||
| 358 | char *targetp = (char *)target; | ||
| 359 | #endif | ||
| 360 | ptrdiff_t delta = targetp - (char *)p; | ||
| 355 | if (A64F_S_OK(delta>>2, 26)) { | 361 | if (A64F_S_OK(delta>>2, 26)) { |
| 356 | *p = A64I_BL | A64F_S26(delta>>2); | 362 | *p = A64I_BL | A64F_S26(delta>>2); |
| 357 | } else { /* Target out of range: need indirect call. But don't use R0-R7. */ | 363 | } else { /* Target out of range: need indirect call. But don't use R0-R7. */ |
| 358 | Reg r = ra_allock(as, i64ptr(target), | 364 | Reg r = ra_allock(as, i64ptr(target), |
| 359 | RSET_RANGE(RID_X8, RID_MAX_GPR)-RSET_FIXED); | 365 | RSET_RANGE(RID_X8, RID_MAX_GPR)-RSET_FIXED); |
| 360 | *p = A64I_BLR | A64F_N(r); | 366 | *p = A64I_BLR_AUTH | A64F_N(r); |
| 361 | } | 367 | } |
| 362 | } | 368 | } |
| 363 | 369 | ||
diff --git a/src/lj_err.c b/src/lj_err.c index 9652ef35..a0a28692 100644 --- a/src/lj_err.c +++ b/src/lj_err.c | |||
| @@ -444,10 +444,10 @@ LJ_FUNCA int lj_err_unwind_dwarf(int version, int actions, | |||
| 444 | if ((actions & _UA_FORCE_UNWIND)) { | 444 | if ((actions & _UA_FORCE_UNWIND)) { |
| 445 | return _URC_CONTINUE_UNWIND; | 445 | return _URC_CONTINUE_UNWIND; |
| 446 | } else if (cf) { | 446 | } else if (cf) { |
| 447 | ASMFunction ip; | ||
| 447 | _Unwind_SetGR(ctx, LJ_TARGET_EHRETREG, errcode); | 448 | _Unwind_SetGR(ctx, LJ_TARGET_EHRETREG, errcode); |
| 448 | _Unwind_SetIP(ctx, (uintptr_t)(cframe_unwind_ff(cf) ? | 449 | ip = cframe_unwind_ff(cf) ? lj_vm_unwind_ff_eh : lj_vm_unwind_c_eh; |
| 449 | lj_vm_unwind_ff_eh : | 450 | _Unwind_SetIP(ctx, (uintptr_t)lj_ptr_strip(ip)); |
| 450 | lj_vm_unwind_c_eh)); | ||
| 451 | return _URC_INSTALL_CONTEXT; | 451 | return _URC_INSTALL_CONTEXT; |
| 452 | } | 452 | } |
| 453 | #if LJ_TARGET_X86ORX64 | 453 | #if LJ_TARGET_X86ORX64 |
| @@ -580,9 +580,17 @@ extern void __deregister_frame(const void *); | |||
| 580 | 580 | ||
| 581 | uint8_t *lj_err_register_mcode(void *base, size_t sz, uint8_t *info) | 581 | uint8_t *lj_err_register_mcode(void *base, size_t sz, uint8_t *info) |
| 582 | { | 582 | { |
| 583 | void **handler; | 583 | ASMFunction handler = (ASMFunction)err_unwind_jit; |
| 584 | memcpy(info, err_frame_jit_template, sizeof(err_frame_jit_template)); | 584 | memcpy(info, err_frame_jit_template, sizeof(err_frame_jit_template)); |
| 585 | handler = (void *)err_unwind_jit; | 585 | #if LJ_ABI_PAUTH |
| 586 | #if LJ_TARGET_ARM64 | ||
| 587 | handler = ptrauth_auth_and_resign(handler, | ||
| 588 | ptrauth_key_function_pointer, 0, | ||
| 589 | ptrauth_key_process_independent_code, info + ERR_FRAME_JIT_OFS_HANDLER); | ||
| 590 | #else | ||
| 591 | #error "missing pointer authentication support for this architecture" | ||
| 592 | #endif | ||
| 593 | #endif | ||
| 586 | memcpy(info + ERR_FRAME_JIT_OFS_HANDLER, &handler, sizeof(handler)); | 594 | memcpy(info + ERR_FRAME_JIT_OFS_HANDLER, &handler, sizeof(handler)); |
| 587 | *(uint32_t *)(info + ERR_FRAME_JIT_OFS_CODE_SIZE) = | 595 | *(uint32_t *)(info + ERR_FRAME_JIT_OFS_CODE_SIZE) = |
| 588 | (uint32_t)(sz - sizeof(err_frame_jit_template) - (info - (uint8_t *)base)); | 596 | (uint32_t)(sz - sizeof(err_frame_jit_template) - (info - (uint8_t *)base)); |
diff --git a/src/lj_jit.h b/src/lj_jit.h index 7f081730..0fae60ad 100644 --- a/src/lj_jit.h +++ b/src/lj_jit.h | |||
| @@ -273,6 +273,9 @@ typedef struct GCtrace { | |||
| 273 | BCIns startins; /* Original bytecode of starting instruction. */ | 273 | BCIns startins; /* Original bytecode of starting instruction. */ |
| 274 | MSize szmcode; /* Size of machine code. */ | 274 | MSize szmcode; /* Size of machine code. */ |
| 275 | MCode *mcode; /* Start of machine code. */ | 275 | MCode *mcode; /* Start of machine code. */ |
| 276 | #if LJ_ABI_PAUTH | ||
| 277 | ASMFunction mcauth; /* Start of machine code, with ptr auth applied. */ | ||
| 278 | #endif | ||
| 276 | MSize mcloop; /* Offset of loop start in machine code. */ | 279 | MSize mcloop; /* Offset of loop start in machine code. */ |
| 277 | uint16_t nchild; /* Number of child traces (root trace only). */ | 280 | uint16_t nchild; /* Number of child traces (root trace only). */ |
| 278 | uint16_t spadjust; /* Stack pointer adjustment (offset in bytes). */ | 281 | uint16_t spadjust; /* Stack pointer adjustment (offset in bytes). */ |
diff --git a/src/lj_obj.h b/src/lj_obj.h index e541387f..52c7bc03 100644 --- a/src/lj_obj.h +++ b/src/lj_obj.h | |||
| @@ -1042,4 +1042,18 @@ LJ_DATA const char *const lj_obj_itypename[~LJ_TNUMX+1]; | |||
| 1042 | LJ_FUNC int LJ_FASTCALL lj_obj_equal(cTValue *o1, cTValue *o2); | 1042 | LJ_FUNC int LJ_FASTCALL lj_obj_equal(cTValue *o1, cTValue *o2); |
| 1043 | LJ_FUNC const void * LJ_FASTCALL lj_obj_ptr(global_State *g, cTValue *o); | 1043 | LJ_FUNC const void * LJ_FASTCALL lj_obj_ptr(global_State *g, cTValue *o); |
| 1044 | 1044 | ||
| 1045 | #if LJ_ABI_PAUTH | ||
| 1046 | #if LJ_TARGET_ARM64 | ||
| 1047 | #include <ptrauth.h> | ||
| 1048 | #define lj_ptr_sign(ptr, ctx) \ | ||
| 1049 | ptrauth_sign_unauthenticated((ptr), ptrauth_key_function_pointer, (ctx)) | ||
| 1050 | #define lj_ptr_strip(ptr) ptrauth_strip((ptr), ptrauth_key_function_pointer) | ||
| 1051 | #else | ||
| 1052 | #error "No support for pointer authentication for this architecture" | ||
| 1053 | #endif | ||
| 1054 | #else | ||
| 1055 | #define lj_ptr_sign(ptr, ctx) (ptr) | ||
| 1056 | #define lj_ptr_strip(ptr) (ptr) | ||
| 1057 | #endif | ||
| 1058 | |||
| 1045 | #endif | 1059 | #endif |
diff --git a/src/lj_target_arm64.h b/src/lj_target_arm64.h index d45af2e4..c9c6b80f 100644 --- a/src/lj_target_arm64.h +++ b/src/lj_target_arm64.h | |||
| @@ -260,6 +260,9 @@ typedef enum A64Ins { | |||
| 260 | A64I_CBZ = 0x34000000, | 260 | A64I_CBZ = 0x34000000, |
| 261 | A64I_CBNZ = 0x35000000, | 261 | A64I_CBNZ = 0x35000000, |
| 262 | 262 | ||
| 263 | A64I_BRAAZ = 0xd61f081f, | ||
| 264 | A64I_BLRAAZ = 0xd63f081f, | ||
| 265 | |||
| 263 | A64I_NOP = 0xd503201f, | 266 | A64I_NOP = 0xd503201f, |
| 264 | 267 | ||
| 265 | /* FP */ | 268 | /* FP */ |
| @@ -317,6 +320,9 @@ typedef enum A64Ins { | |||
| 317 | A64I_FMOV_DI = 0x1e601000, | 320 | A64I_FMOV_DI = 0x1e601000, |
| 318 | } A64Ins; | 321 | } A64Ins; |
| 319 | 322 | ||
| 323 | #define A64I_BR_AUTH (LJ_ABI_PAUTH ? A64I_BRAAZ : A64I_BR) | ||
| 324 | #define A64I_BLR_AUTH (LJ_ABI_PAUTH ? A64I_BLRAAZ : A64I_BLR) | ||
| 325 | |||
| 320 | typedef enum A64Shift { | 326 | typedef enum A64Shift { |
| 321 | A64SH_LSL, A64SH_LSR, A64SH_ASR, A64SH_ROR | 327 | A64SH_LSL, A64SH_LSR, A64SH_ASR, A64SH_ROR |
| 322 | } A64Shift; | 328 | } A64Shift; |
diff --git a/src/lj_trace.c b/src/lj_trace.c index c2329394..03c8d1d0 100644 --- a/src/lj_trace.c +++ b/src/lj_trace.c | |||
| @@ -153,6 +153,9 @@ static void trace_save(jit_State *J, GCtrace *T) | |||
| 153 | newwhite(J2G(J), T); | 153 | newwhite(J2G(J), T); |
| 154 | T->gct = ~LJ_TTRACE; | 154 | T->gct = ~LJ_TTRACE; |
| 155 | T->ir = (IRIns *)p - J->cur.nk; /* The IR has already been copied above. */ | 155 | T->ir = (IRIns *)p - J->cur.nk; /* The IR has already been copied above. */ |
| 156 | #if LJ_ABI_PAUTH | ||
| 157 | T->mcauth = lj_ptr_sign((ASMFunction)T->mcode, T); | ||
| 158 | #endif | ||
| 156 | p += szins; | 159 | p += szins; |
| 157 | TRACE_APPENDVEC(snap, nsnap, SnapShot) | 160 | TRACE_APPENDVEC(snap, nsnap, SnapShot) |
| 158 | TRACE_APPENDVEC(snapmap, nsnapmap, SnapEntry) | 161 | TRACE_APPENDVEC(snapmap, nsnapmap, SnapEntry) |
diff --git a/src/lj_vm.h b/src/lj_vm.h index c66db004..c7095941 100644 --- a/src/lj_vm.h +++ b/src/lj_vm.h | |||
| @@ -54,8 +54,8 @@ LJ_ASMF void lj_vm_profhook(void); | |||
| 54 | LJ_ASMF void lj_vm_IITERN(void); | 54 | LJ_ASMF void lj_vm_IITERN(void); |
| 55 | 55 | ||
| 56 | /* Trace exit handling. */ | 56 | /* Trace exit handling. */ |
| 57 | LJ_ASMF void lj_vm_exit_handler(void); | 57 | LJ_ASMF char lj_vm_exit_handler[]; |
| 58 | LJ_ASMF void lj_vm_exit_interp(void); | 58 | LJ_ASMF char lj_vm_exit_interp[]; |
| 59 | 59 | ||
| 60 | /* Internal math helper functions. */ | 60 | /* Internal math helper functions. */ |
| 61 | #if LJ_TARGET_PPC || LJ_TARGET_ARM64 || (LJ_TARGET_MIPS && LJ_ABI_SOFTFP) | 61 | #if LJ_TARGET_PPC || LJ_TARGET_ARM64 || (LJ_TARGET_MIPS && LJ_ABI_SOFTFP) |
| @@ -111,6 +111,6 @@ LJ_ASMF void lj_cont_stitch(void); /* Trace stitching. */ | |||
| 111 | LJ_ASMF char lj_vm_asm_begin[]; | 111 | LJ_ASMF char lj_vm_asm_begin[]; |
| 112 | 112 | ||
| 113 | /* Bytecode offsets are relative to lj_vm_asm_begin. */ | 113 | /* Bytecode offsets are relative to lj_vm_asm_begin. */ |
| 114 | #define makeasmfunc(ofs) ((ASMFunction)(lj_vm_asm_begin + (ofs))) | 114 | #define makeasmfunc(ofs) lj_ptr_sign((ASMFunction)(lj_vm_asm_begin + (ofs)), 0) |
| 115 | 115 | ||
| 116 | #endif | 116 | #endif |
diff --git a/src/vm_arm64.dasc b/src/vm_arm64.dasc index 36a036ae..d45cc86b 100644 --- a/src/vm_arm64.dasc +++ b/src/vm_arm64.dasc | |||
| @@ -77,6 +77,23 @@ | |||
| 77 | |.define CRET1, x0 | 77 | |.define CRET1, x0 |
| 78 | |.define CRET1w, w0 | 78 | |.define CRET1w, w0 |
| 79 | | | 79 | | |
| 80 | |//----------------------------------------------------------------------- | ||
| 81 | | | ||
| 82 | |// ARM64e pointer authentication codes (PAC). | ||
| 83 | |.if PAUTH | ||
| 84 | |.macro sp_auth; pacibsp; .endmacro | ||
| 85 | |.macro br_auth, reg; braaz reg; .endmacro | ||
| 86 | |.macro blr_auth, reg; blraaz reg; .endmacro | ||
| 87 | |.macro ret_auth; retab; .endmacro | ||
| 88 | |.else | ||
| 89 | |.macro sp_auth; .endmacro | ||
| 90 | |.macro br_auth, reg; br reg; .endmacro | ||
| 91 | |.macro blr_auth, reg; blr reg; .endmacro | ||
| 92 | |.macro ret_auth; ret; .endmacro | ||
| 93 | |.endif | ||
| 94 | | | ||
| 95 | |//----------------------------------------------------------------------- | ||
| 96 | | | ||
| 80 | |// Stack layout while in interpreter. Must match with lj_frame.h. | 97 | |// Stack layout while in interpreter. Must match with lj_frame.h. |
| 81 | | | 98 | | |
| 82 | |.define CFRAME_SPACE, 208 | 99 | |.define CFRAME_SPACE, 208 |
| @@ -106,6 +123,7 @@ | |||
| 106 | |.endmacro | 123 | |.endmacro |
| 107 | | | 124 | | |
| 108 | |.macro saveregs | 125 | |.macro saveregs |
| 126 | | sp_auth | ||
| 109 | | sub sp, sp, # CFRAME_SPACE | 127 | | sub sp, sp, # CFRAME_SPACE |
| 110 | | stp fp, lr, [sp, # SAVE_FP_LR_] | 128 | | stp fp, lr, [sp, # SAVE_FP_LR_] |
| 111 | | add fp, sp, # SAVE_FP_LR_ | 129 | | add fp, sp, # SAVE_FP_LR_ |
| @@ -180,7 +198,7 @@ | |||
| 180 | | decode_RA RA, INS | 198 | | decode_RA RA, INS |
| 181 | | ldr TMP0, [TMP1, #GG_G2DISP] | 199 | | ldr TMP0, [TMP1, #GG_G2DISP] |
| 182 | | decode_RD RC, INS | 200 | | decode_RD RC, INS |
| 183 | | br TMP0 | 201 | | br_auth TMP0 |
| 184 | |.endmacro | 202 | |.endmacro |
| 185 | | | 203 | | |
| 186 | |// Instruction footer. | 204 | |// Instruction footer. |
| @@ -209,7 +227,7 @@ | |||
| 209 | | decode_RA RA, INS | 227 | | decode_RA RA, INS |
| 210 | | ldr TMP0, [TMP1, #GG_G2DISP] | 228 | | ldr TMP0, [TMP1, #GG_G2DISP] |
| 211 | | add RA, BASE, RA, lsl #3 | 229 | | add RA, BASE, RA, lsl #3 |
| 212 | | br TMP0 | 230 | | br_auth TMP0 |
| 213 | |.endmacro | 231 | |.endmacro |
| 214 | | | 232 | | |
| 215 | |.macro ins_call | 233 | |.macro ins_call |
| @@ -356,7 +374,7 @@ static void build_subroutines(BuildCtx *ctx) | |||
| 356 | | | 374 | | |
| 357 | |->vm_leave_unw: | 375 | |->vm_leave_unw: |
| 358 | | restoreregs | 376 | | restoreregs |
| 359 | | ret | 377 | | ret_auth |
| 360 | | | 378 | | |
| 361 | |6: | 379 | |6: |
| 362 | | bgt >7 // Less results wanted? | 380 | | bgt >7 // Less results wanted? |
| @@ -542,7 +560,7 @@ static void build_subroutines(BuildCtx *ctx) | |||
| 542 | | str RC, SAVE_CFRAME | 560 | | str RC, SAVE_CFRAME |
| 543 | | str TMP0, L->cframe // Add our C frame to cframe chain. | 561 | | str TMP0, L->cframe // Add our C frame to cframe chain. |
| 544 | | str L, GL->cur_L | 562 | | str L, GL->cur_L |
| 545 | | blr CARG4 // (lua_State *L, lua_CFunction func, void *ud) | 563 | | blr_auth CARG4 // (lua_State *L, lua_CFunction func, void *ud) |
| 546 | | mov BASE, CRET1 | 564 | | mov BASE, CRET1 |
| 547 | | mov PC, #FRAME_CP | 565 | | mov PC, #FRAME_CP |
| 548 | | cbnz BASE, <3 // Else continue with the call. | 566 | | cbnz BASE, <3 // Else continue with the call. |
| @@ -573,7 +591,7 @@ static void build_subroutines(BuildCtx *ctx) | |||
| 573 | | ldr CARG3, LFUNC:CARG3->pc | 591 | | ldr CARG3, LFUNC:CARG3->pc |
| 574 | | ldr KBASE, [CARG3, #PC2PROTO(k)] | 592 | | ldr KBASE, [CARG3, #PC2PROTO(k)] |
| 575 | | // BASE = base, RA = resultptr, CARG4 = meta base | 593 | | // BASE = base, RA = resultptr, CARG4 = meta base |
| 576 | | br CARG1 | 594 | | br_auth CARG1 |
| 577 | | | 595 | | |
| 578 | |.if FFI | 596 | |.if FFI |
| 579 | |1: | 597 | |1: |
| @@ -1707,7 +1725,7 @@ static void build_subroutines(BuildCtx *ctx) | |||
| 1707 | | cmp TMP1, TMP2 | 1725 | | cmp TMP1, TMP2 |
| 1708 | | mov CARG1, L | 1726 | | mov CARG1, L |
| 1709 | | bhi >5 // Need to grow stack. | 1727 | | bhi >5 // Need to grow stack. |
| 1710 | | blr CARG3 // (lua_State *L) | 1728 | | blr_auth CARG3 // (lua_State *L) |
| 1711 | | // Either throws an error, or recovers and returns -1, 0 or nresults+1. | 1729 | | // Either throws an error, or recovers and returns -1, 0 or nresults+1. |
| 1712 | | ldr BASE, L->base | 1730 | | ldr BASE, L->base |
| 1713 | | cmp CRET1w, #0 | 1731 | | cmp CRET1w, #0 |
| @@ -1743,6 +1761,7 @@ static void build_subroutines(BuildCtx *ctx) | |||
| 1743 | | | 1761 | | |
| 1744 | |->fff_gcstep: // Call GC step function. | 1762 | |->fff_gcstep: // Call GC step function. |
| 1745 | | // BASE = new base, RC = nargs*8 | 1763 | | // BASE = new base, RC = nargs*8 |
| 1764 | | sp_auth | ||
| 1746 | | add CARG2, BASE, NARGS8:RC // Calculate L->top. | 1765 | | add CARG2, BASE, NARGS8:RC // Calculate L->top. |
| 1747 | | mov RA, lr | 1766 | | mov RA, lr |
| 1748 | | stp BASE, CARG2, L->base | 1767 | | stp BASE, CARG2, L->base |
| @@ -1754,7 +1773,7 @@ static void build_subroutines(BuildCtx *ctx) | |||
| 1754 | | mov lr, RA // Help return address predictor. | 1773 | | mov lr, RA // Help return address predictor. |
| 1755 | | sub NARGS8:RC, CARG2, BASE // Calculate nargs*8. | 1774 | | sub NARGS8:RC, CARG2, BASE // Calculate nargs*8. |
| 1756 | | and CFUNC:CARG3, CARG3, #LJ_GCVMASK | 1775 | | and CFUNC:CARG3, CARG3, #LJ_GCVMASK |
| 1757 | | ret | 1776 | | ret_auth |
| 1758 | | | 1777 | | |
| 1759 | |//----------------------------------------------------------------------- | 1778 | |//----------------------------------------------------------------------- |
| 1760 | |//-- Special dispatch targets ------------------------------------------- | 1779 | |//-- Special dispatch targets ------------------------------------------- |
| @@ -1781,7 +1800,7 @@ static void build_subroutines(BuildCtx *ctx) | |||
| 1781 | | tbz TMP2w, #HOOK_ACTIVE_SHIFT, >1 // Hook already active? | 1800 | | tbz TMP2w, #HOOK_ACTIVE_SHIFT, >1 // Hook already active? |
| 1782 | |5: // Re-dispatch to static ins. | 1801 | |5: // Re-dispatch to static ins. |
| 1783 | | ldr TMP0, [TMP1, #GG_G2DISP+GG_DISP2STATIC] | 1802 | | ldr TMP0, [TMP1, #GG_G2DISP+GG_DISP2STATIC] |
| 1784 | | br TMP0 | 1803 | | br_auth TMP0 |
| 1785 | | | 1804 | | |
| 1786 | |->vm_inshook: // Dispatch target for instr/line hooks. | 1805 | |->vm_inshook: // Dispatch target for instr/line hooks. |
| 1787 | | ldrb TMP2w, GL->hookmask | 1806 | | ldrb TMP2w, GL->hookmask |
| @@ -1807,7 +1826,7 @@ static void build_subroutines(BuildCtx *ctx) | |||
| 1807 | | decode_RA RA, INS | 1826 | | decode_RA RA, INS |
| 1808 | | ldr TMP0, [TMP1, #GG_G2DISP+GG_DISP2STATIC] | 1827 | | ldr TMP0, [TMP1, #GG_G2DISP+GG_DISP2STATIC] |
| 1809 | | decode_RD RC, INS | 1828 | | decode_RD RC, INS |
| 1810 | | br TMP0 | 1829 | | br_auth TMP0 |
| 1811 | | | 1830 | | |
| 1812 | |->cont_hook: // Continue from hook yield. | 1831 | |->cont_hook: // Continue from hook yield. |
| 1813 | | ldr CARG1, [CARG4, #-40] | 1832 | | ldr CARG1, [CARG4, #-40] |
| @@ -1857,7 +1876,7 @@ static void build_subroutines(BuildCtx *ctx) | |||
| 1857 | | sub NARGS8:RC, TMP1, BASE | 1876 | | sub NARGS8:RC, TMP1, BASE |
| 1858 | | ldr INSw, [PC, #-4] | 1877 | | ldr INSw, [PC, #-4] |
| 1859 | | and LFUNC:CARG3, CARG3, #LJ_GCVMASK | 1878 | | and LFUNC:CARG3, CARG3, #LJ_GCVMASK |
| 1860 | | br CRET1 | 1879 | | br_auth CRET1 |
| 1861 | | | 1880 | | |
| 1862 | |->cont_stitch: // Trace stitching. | 1881 | |->cont_stitch: // Trace stitching. |
| 1863 | |.if JIT | 1882 | |.if JIT |
| @@ -2020,7 +2039,7 @@ static void build_subroutines(BuildCtx *ctx) | |||
| 2020 | | add RA, BASE, RA, lsl #3 // Yes: RA = BASE+framesize*8, RC = nargs*8 | 2039 | | add RA, BASE, RA, lsl #3 // Yes: RA = BASE+framesize*8, RC = nargs*8 |
| 2021 | | and LFUNC:CARG3, CARG3, #LJ_GCVMASK | 2040 | | and LFUNC:CARG3, CARG3, #LJ_GCVMASK |
| 2022 | |5: | 2041 | |5: |
| 2023 | | br RB | 2042 | | br_auth RB |
| 2024 | | | 2043 | | |
| 2025 | |4: // Check frame below fast function. | 2044 | |4: // Check frame below fast function. |
| 2026 | | ldr CARG1, [BASE, FRAME_PC] | 2045 | | ldr CARG1, [BASE, FRAME_PC] |
| @@ -2182,6 +2201,7 @@ static void build_subroutines(BuildCtx *ctx) | |||
| 2182 | | // Caveat: needs special frame unwinding, see below. | 2201 | | // Caveat: needs special frame unwinding, see below. |
| 2183 | |.if FFI | 2202 | |.if FFI |
| 2184 | | .type CCSTATE, CCallState, x19 | 2203 | | .type CCSTATE, CCallState, x19 |
| 2204 | | sp_auth | ||
| 2185 | | stp x20, CCSTATE, [sp, #-32]! | 2205 | | stp x20, CCSTATE, [sp, #-32]! |
| 2186 | | stp fp, lr, [sp, #16] | 2206 | | stp fp, lr, [sp, #16] |
| 2187 | | add fp, sp, #16 | 2207 | | add fp, sp, #16 |
| @@ -2208,14 +2228,14 @@ static void build_subroutines(BuildCtx *ctx) | |||
| 2208 | | ldp x6, x7, CCSTATE->gpr[6] | 2228 | | ldp x6, x7, CCSTATE->gpr[6] |
| 2209 | | ldp d6, d7, CCSTATE->fpr[6] | 2229 | | ldp d6, d7, CCSTATE->fpr[6] |
| 2210 | | ldr x8, CCSTATE->retp | 2230 | | ldr x8, CCSTATE->retp |
| 2211 | | blr TMP3 | 2231 | | blr_auth TMP3 |
| 2212 | | sub sp, fp, #16 | 2232 | | sub sp, fp, #16 |
| 2213 | | stp x0, x1, CCSTATE->gpr[0] | 2233 | | stp x0, x1, CCSTATE->gpr[0] |
| 2214 | | stp d0, d1, CCSTATE->fpr[0] | 2234 | | stp d0, d1, CCSTATE->fpr[0] |
| 2215 | | stp d2, d3, CCSTATE->fpr[2] | 2235 | | stp d2, d3, CCSTATE->fpr[2] |
| 2216 | | ldp fp, lr, [sp, #16] | 2236 | | ldp fp, lr, [sp, #16] |
| 2217 | | ldp x20, CCSTATE, [sp], #32 | 2237 | | ldp x20, CCSTATE, [sp], #32 |
| 2218 | | ret | 2238 | | ret_auth |
| 2219 | |.endif | 2239 | |.endif |
| 2220 | |// Note: vm_ffi_call must be the last function in this object file! | 2240 | |// Note: vm_ffi_call must be the last function in this object file! |
| 2221 | | | 2241 | | |
| @@ -3786,12 +3806,20 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop) | |||
| 3786 | | mov CARG2w, #0 // Traces on ARM64 don't store the trace #, so use 0. | 3806 | | mov CARG2w, #0 // Traces on ARM64 don't store the trace #, so use 0. |
| 3787 | | ldr TRACE:RC, [CARG1, RC, lsl #3] | 3807 | | ldr TRACE:RC, [CARG1, RC, lsl #3] |
| 3788 | | st_vmstate CARG2w | 3808 | | st_vmstate CARG2w |
| 3809 | |.if PAUTH | ||
| 3810 | | ldr RA, TRACE:RC->mcauth | ||
| 3811 | |.else | ||
| 3789 | | ldr RA, TRACE:RC->mcode | 3812 | | ldr RA, TRACE:RC->mcode |
| 3813 | |.endif | ||
| 3790 | | str BASE, GL->jit_base | 3814 | | str BASE, GL->jit_base |
| 3791 | | str L, GL->tmpbuf.L | 3815 | | str L, GL->tmpbuf.L |
| 3792 | | sub sp, sp, #16 // See SPS_FIXED. Avoids sp adjust in every root trace. | 3816 | | sub sp, sp, #16 // See SPS_FIXED. Avoids sp adjust in every root trace. |
| 3817 | |.if PAUTH | ||
| 3818 | | braa RA, RC | ||
| 3819 | |.else | ||
| 3793 | | br RA | 3820 | | br RA |
| 3794 | |.endif | 3821 | |.endif |
| 3822 | |.endif | ||
| 3795 | break; | 3823 | break; |
| 3796 | 3824 | ||
| 3797 | case BC_JMP: | 3825 | case BC_JMP: |
| @@ -3901,7 +3929,7 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop) | |||
| 3901 | | mov CARG1, L | 3929 | | mov CARG1, L |
| 3902 | | bhi ->vm_growstack_c // Need to grow stack. | 3930 | | bhi ->vm_growstack_c // Need to grow stack. |
| 3903 | | st_vmstate TMP0w | 3931 | | st_vmstate TMP0w |
| 3904 | | blr CARG4 // (lua_State *L [, lua_CFunction f]) | 3932 | | blr_auth CARG4 // (lua_State *L [, lua_CFunction f]) |
| 3905 | | // Returns nresults. | 3933 | | // Returns nresults. |
| 3906 | | ldp BASE, TMP1, L->base | 3934 | | ldp BASE, TMP1, L->base |
| 3907 | | str L, GL->cur_L | 3935 | | str L, GL->cur_L |
