aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Pall <mike>2023-08-12 22:25:40 +0200
committerMike Pall <mike>2023-08-12 22:25:40 +0200
commit27af72e66f6a285298d1a9be370779aae945eb14 (patch)
tree5b12777dac86ab8afbdfd337af020f1d1da0f044
parent117ddf35e6ef1bb9016881f828337677db493cee (diff)
downloadluajit-27af72e66f6a285298d1a9be370779aae945eb14.tar.gz
luajit-27af72e66f6a285298d1a9be370779aae945eb14.tar.bz2
luajit-27af72e66f6a285298d1a9be370779aae945eb14.zip
ARM64: Add support for ARM64e pointer authentication codes (PAC).
Contributed by Peter Cawley. #559
-rw-r--r--doc/ext_ffi_api.html4
-rw-r--r--src/Makefile4
-rw-r--r--src/lib_ffi.c3
-rw-r--r--src/lib_jit.c3
-rw-r--r--src/lj_arch.h7
-rw-r--r--src/lj_asm_arm64.h6
-rw-r--r--src/lj_ccallback.c6
-rw-r--r--src/lj_emit_arm64.h12
-rw-r--r--src/lj_err.c18
-rw-r--r--src/lj_jit.h3
-rw-r--r--src/lj_obj.h14
-rw-r--r--src/lj_target_arm64.h6
-rw-r--r--src/lj_trace.c3
-rw-r--r--src/lj_vm.h6
-rw-r--r--src/vm_arm64.dasc56
15 files changed, 118 insertions, 33 deletions
diff --git a/doc/ext_ffi_api.html b/doc/ext_ffi_api.html
index 89ddb0d9..8e99ff48 100644
--- a/doc/ext_ffi_api.html
+++ b/doc/ext_ffi_api.html
@@ -463,8 +463,10 @@ otherwise. The following parameters are currently defined:
463<tr class="odd"> 463<tr class="odd">
464<td class="abiparam">win</td><td class="abidesc">Windows variant of the standard ABI</td></tr> 464<td class="abiparam">win</td><td class="abidesc">Windows variant of the standard ABI</td></tr>
465<tr class="even"> 465<tr class="even">
466<td class="abiparam">uwp</td><td class="abidesc">Universal Windows Platform</td></tr> 466<td class="abiparam">pauth</td><td class="abidesc">Pointer authentication ABI</td></tr>
467<tr class="odd"> 467<tr class="odd">
468<td class="abiparam">uwp</td><td class="abidesc">Universal Windows Platform</td></tr>
469<tr class="even">
468<td class="abiparam">gc64</td><td class="abidesc">64 bit GC references</td></tr> 470<td class="abiparam">gc64</td><td class="abidesc">64 bit GC references</td></tr>
469</table> 471</table>
470 472
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
435endif 435endif
436ifneq (,$(findstring LJ_ABI_PAUTH 1,$(TARGET_TESTARCH)))
437 DASM_AFLAGS+= -D PAUTH
438 TARGET_ARCH+= -DLJ_ABI_PAUTH=1
439endif
436DASM_AFLAGS+= -D VER=$(subst LJ_ARCH_VERSION_,,$(filter LJ_ARCH_VERSION_%,$(subst LJ_ARCH_VERSION ,LJ_ARCH_VERSION_,$(TARGET_TESTARCH)))) 440DASM_AFLAGS+= -D VER=$(subst LJ_ARCH_VERSION_,,$(filter LJ_ARCH_VERSION_%,$(subst LJ_ARCH_VERSION ,LJ_ARCH_VERSION_,$(TARGET_TESTARCH))))
437ifeq (Windows,$(TARGET_SYS)) 441ifeq (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)
171static void *callback_mcode_init(global_State *g, uint32_t *page) 171static 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
351static void emit_call(ASMState *as, void *target) 351static 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
581uint8_t *lj_err_register_mcode(void *base, size_t sz, uint8_t *info) 581uint8_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];
1042LJ_FUNC int LJ_FASTCALL lj_obj_equal(cTValue *o1, cTValue *o2); 1042LJ_FUNC int LJ_FASTCALL lj_obj_equal(cTValue *o1, cTValue *o2);
1043LJ_FUNC const void * LJ_FASTCALL lj_obj_ptr(global_State *g, cTValue *o); 1043LJ_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
320typedef enum A64Shift { 326typedef 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);
54LJ_ASMF void lj_vm_IITERN(void); 54LJ_ASMF void lj_vm_IITERN(void);
55 55
56/* Trace exit handling. */ 56/* Trace exit handling. */
57LJ_ASMF void lj_vm_exit_handler(void); 57LJ_ASMF char lj_vm_exit_handler[];
58LJ_ASMF void lj_vm_exit_interp(void); 58LJ_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. */
111LJ_ASMF char lj_vm_asm_begin[]; 111LJ_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