aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Pall <mike>2021-09-20 22:37:07 +0200
committerMike Pall <mike>2021-09-20 22:37:07 +0200
commit421c4c798791d27b7f967df39891c4e4fa1d107c (patch)
tree2048dc80df764a3952fb5024ec687bd8d77edf3c
parent28440544ba7fc494ecc822c37750991a101e41cd (diff)
downloadluajit-421c4c798791d27b7f967df39891c4e4fa1d107c.tar.gz
luajit-421c4c798791d27b7f967df39891c4e4fa1d107c.tar.bz2
luajit-421c4c798791d27b7f967df39891c4e4fa1d107c.zip
ARM64: Reorder interpreter stack frame and fix unwinding.
Reported by Yichun Zhang. Fixes #722. May help towards fixing #698, too.
-rw-r--r--src/lj_frame.h12
-rw-r--r--src/vm_arm64.dasc189
2 files changed, 152 insertions, 49 deletions
diff --git a/src/lj_frame.h b/src/lj_frame.h
index f67a2332..b6146454 100644
--- a/src/lj_frame.h
+++ b/src/lj_frame.h
@@ -192,12 +192,12 @@ enum { LJ_CONT_TAILCALL, LJ_CONT_FFI_CALLBACK }; /* Special continuations. */
192#endif 192#endif
193#define CFRAME_SHIFT_MULTRES 3 193#define CFRAME_SHIFT_MULTRES 3
194#elif LJ_TARGET_ARM64 194#elif LJ_TARGET_ARM64
195#define CFRAME_OFS_ERRF 196 195#define CFRAME_OFS_ERRF 36
196#define CFRAME_OFS_NRES 200 196#define CFRAME_OFS_NRES 40
197#define CFRAME_OFS_PREV 160 197#define CFRAME_OFS_PREV 0
198#define CFRAME_OFS_L 176 198#define CFRAME_OFS_L 16
199#define CFRAME_OFS_PC 168 199#define CFRAME_OFS_PC 8
200#define CFRAME_OFS_MULTRES 192 200#define CFRAME_OFS_MULTRES 32
201#define CFRAME_SIZE 208 201#define CFRAME_SIZE 208
202#define CFRAME_SHIFT_MULTRES 3 202#define CFRAME_SHIFT_MULTRES 3
203#elif LJ_TARGET_PPC 203#elif LJ_TARGET_PPC
diff --git a/src/vm_arm64.dasc b/src/vm_arm64.dasc
index 304e4544..bc9fc456 100644
--- a/src/vm_arm64.dasc
+++ b/src/vm_arm64.dasc
@@ -81,47 +81,49 @@
81| 81|
82|.define CFRAME_SPACE, 208 82|.define CFRAME_SPACE, 208
83|//----- 16 byte aligned, <-- sp entering interpreter 83|//----- 16 byte aligned, <-- sp entering interpreter
84|// Unused [sp, #204] // 32 bit values 84|.define SAVE_LR, [sp, #200]
85|.define SAVE_NRES, [sp, #200] 85|.define SAVE_FP, [sp, #192]
86|.define SAVE_ERRF, [sp, #196] 86|.define SAVE_GPR_, 112 // 112+10*8: 64 bit GPR saves
87|.define SAVE_MULTRES, [sp, #192] 87|.define SAVE_FPR_, 48 // 48+8*8: 64 bit FPR saves
88|.define TMPD, [sp, #184] // 64 bit values 88|// Unused [sp, #44] // 32 bit values
89|.define SAVE_L, [sp, #176] 89|.define SAVE_NRES, [sp, #40]
90|.define SAVE_PC, [sp, #168] 90|.define SAVE_ERRF, [sp, #36]
91|.define SAVE_CFRAME, [sp, #160] 91|.define SAVE_MULTRES, [sp, #32]
92|.define SAVE_FPR_, 96 // 96+8*8: 64 bit FPR saves 92|.define TMPD, [sp, #24] // 64 bit values
93|.define SAVE_GPR_, 16 // 16+10*8: 64 bit GPR saves 93|.define SAVE_L, [sp, #16]
94|.define SAVE_LR, [sp, #8] 94|.define SAVE_PC, [sp, #8]
95|.define SAVE_FP, [sp] 95|.define SAVE_CFRAME, [sp, #0]
96|//----- 16 byte aligned, <-- sp while in interpreter. 96|//----- 16 byte aligned, <-- sp while in interpreter.
97| 97|
98|.define TMPDofs, #184 98|.define TMPDofs, #24
99| 99|
100|.macro save_, gpr1, gpr2, fpr1, fpr2 100|.macro save_, gpr1, gpr2, fpr1, fpr2
101| stp d..fpr1, d..fpr2, [sp, # SAVE_FPR_+(fpr1-8)*8] 101| stp d..fpr2, d..fpr1, [sp, # SAVE_FPR_+(14-fpr1)*8]
102| stp x..gpr1, x..gpr2, [sp, # SAVE_GPR_+(gpr1-19)*8] 102| stp x..gpr2, x..gpr1, [sp, # SAVE_GPR_+(27-gpr1)*8]
103|.endmacro 103|.endmacro
104|.macro rest_, gpr1, gpr2, fpr1, fpr2 104|.macro rest_, gpr1, gpr2, fpr1, fpr2
105| ldp d..fpr1, d..fpr2, [sp, # SAVE_FPR_+(fpr1-8)*8] 105| ldp d..fpr2, d..fpr1, [sp, # SAVE_FPR_+(14-fpr1)*8]
106| ldp x..gpr1, x..gpr2, [sp, # SAVE_GPR_+(gpr1-19)*8] 106| ldp x..gpr2, x..gpr1, [sp, # SAVE_GPR_+(27-gpr1)*8]
107|.endmacro 107|.endmacro
108| 108|
109|.macro saveregs 109|.macro saveregs
110| stp fp, lr, [sp, #-CFRAME_SPACE]! 110| sub sp, sp, # CFRAME_SPACE
111| stp fp, lr, SAVE_FP
111| add fp, sp, #0 112| add fp, sp, #0
112| stp x19, x20, [sp, # SAVE_GPR_] 113| stp x20, x19, [sp, # SAVE_GPR_+(27-19)*8]
113| save_ 21, 22, 8, 9 114| save_ 21, 22, 8, 9
114| save_ 23, 24, 10, 11 115| save_ 23, 24, 10, 11
115| save_ 25, 26, 12, 13 116| save_ 25, 26, 12, 13
116| save_ 27, 28, 14, 15 117| save_ 27, 28, 14, 15
117|.endmacro 118|.endmacro
118|.macro restoreregs 119|.macro restoreregs
119| ldp x19, x20, [sp, # SAVE_GPR_] 120| ldp x20, x19, [sp, # SAVE_GPR_+(27-19)*8]
120| rest_ 21, 22, 8, 9 121| rest_ 21, 22, 8, 9
121| rest_ 23, 24, 10, 11 122| rest_ 23, 24, 10, 11
122| rest_ 25, 26, 12, 13 123| rest_ 25, 26, 12, 13
123| rest_ 27, 28, 14, 15 124| rest_ 27, 28, 14, 15
124| ldp fp, lr, [sp], # CFRAME_SPACE 125| ldp fp, lr, SAVE_FP
126| add sp, sp, # CFRAME_SPACE
125|.endmacro 127|.endmacro
126| 128|
127|// Type definitions. Some of these are only used for documentation. 129|// Type definitions. Some of these are only used for documentation.
@@ -2178,9 +2180,9 @@ static void build_subroutines(BuildCtx *ctx)
2178 | // Caveat: needs special frame unwinding, see below. 2180 | // Caveat: needs special frame unwinding, see below.
2179 |.if FFI 2181 |.if FFI
2180 | .type CCSTATE, CCallState, x19 2182 | .type CCSTATE, CCallState, x19
2181 | stp fp, lr, [sp, #-32]! 2183 | stp x20, CCSTATE, [sp, #-32]!
2184 | stp fp, lr, [sp, #16]
2182 | add fp, sp, #0 2185 | add fp, sp, #0
2183 | str CCSTATE, [sp, #16]
2184 | mov CCSTATE, x0 2186 | mov CCSTATE, x0
2185 | ldr TMP0w, CCSTATE:x0->spadj 2187 | ldr TMP0w, CCSTATE:x0->spadj
2186 | ldrb TMP1w, CCSTATE->nsp 2188 | ldrb TMP1w, CCSTATE->nsp
@@ -2209,8 +2211,8 @@ static void build_subroutines(BuildCtx *ctx)
2209 | stp x0, x1, CCSTATE->gpr[0] 2211 | stp x0, x1, CCSTATE->gpr[0]
2210 | stp d0, d1, CCSTATE->fpr[0] 2212 | stp d0, d1, CCSTATE->fpr[0]
2211 | stp d2, d3, CCSTATE->fpr[2] 2213 | stp d2, d3, CCSTATE->fpr[2]
2212 | ldr CCSTATE, [sp, #16] 2214 | ldp fp, lr, [sp, #16]
2213 | ldp fp, lr, [sp], #32 2215 | ldp x20, CCSTATE, [sp], #32
2214 | ret 2216 | ret
2215 |.endif 2217 |.endif
2216 |// Note: vm_ffi_call must be the last function in this object file! 2218 |// Note: vm_ffi_call must be the last function in this object file!
@@ -2940,7 +2942,7 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop)
2940 case BC_GGET: 2942 case BC_GGET:
2941 | // RA = dst, RC = str_const (~) 2943 | // RA = dst, RC = str_const (~)
2942 case BC_GSET: 2944 case BC_GSET:
2943 | // RA = dst, RC = str_const (~) 2945 | // RA = src, RC = str_const (~)
2944 | ldr LFUNC:CARG1, [BASE, FRAME_FUNC] 2946 | ldr LFUNC:CARG1, [BASE, FRAME_FUNC]
2945 | mvn RC, RC 2947 | mvn RC, RC
2946 | and LFUNC:CARG1, CARG1, #LJ_GCVMASK 2948 | and LFUNC:CARG1, CARG1, #LJ_GCVMASK
@@ -3934,7 +3936,7 @@ static int build_backend(BuildCtx *ctx)
3934static void emit_asm_debug(BuildCtx *ctx) 3936static void emit_asm_debug(BuildCtx *ctx)
3935{ 3937{
3936 int fcofs = (int)((uint8_t *)ctx->glob[GLOB_vm_ffi_call] - ctx->code); 3938 int fcofs = (int)((uint8_t *)ctx->glob[GLOB_vm_ffi_call] - ctx->code);
3937 int i, cf = CFRAME_SIZE >> 3; 3939 int i;
3938 switch (ctx->mode) { 3940 switch (ctx->mode) {
3939 case BUILD_elfasm: 3941 case BUILD_elfasm:
3940 fprintf(ctx->fp, "\t.section .debug_frame,\"\",%%progbits\n"); 3942 fprintf(ctx->fp, "\t.section .debug_frame,\"\",%%progbits\n");
@@ -3959,14 +3961,14 @@ static void emit_asm_debug(BuildCtx *ctx)
3959 "\t.quad .Lbegin\n" 3961 "\t.quad .Lbegin\n"
3960 "\t.quad %d\n" 3962 "\t.quad %d\n"
3961 "\t.byte 0xe\n\t.uleb128 %d\n" /* def_cfa_offset */ 3963 "\t.byte 0xe\n\t.uleb128 %d\n" /* def_cfa_offset */
3962 "\t.byte 0x9d\n\t.uleb128 %d\n" /* offset fp */ 3964 "\t.byte 0x9e\n\t.uleb128 1\n" /* offset lr */
3963 "\t.byte 0x9e\n\t.uleb128 %d\n", /* offset lr */ 3965 "\t.byte 0x9d\n\t.uleb128 2\n", /* offset fp */
3964 fcofs, CFRAME_SIZE, cf, cf-1); 3966 fcofs, CFRAME_SIZE);
3965 for (i = 19; i <= 28; i++) /* offset x19-x28 */ 3967 for (i = 19; i <= 28; i++) /* offset x19-x28 */
3966 fprintf(ctx->fp, "\t.byte 0x%x\n\t.uleb128 %d\n", 0x80+i, cf-i+17); 3968 fprintf(ctx->fp, "\t.byte 0x%x\n\t.uleb128 %d\n", 0x80+i, i+(3-19));
3967 for (i = 8; i <= 15; i++) /* offset d8-d15 */ 3969 for (i = 8; i <= 15; i++) /* offset d8-d15 */
3968 fprintf(ctx->fp, "\t.byte 5\n\t.uleb128 0x%x\n\t.uleb128 %d\n", 3970 fprintf(ctx->fp, "\t.byte 5\n\t.uleb128 0x%x\n\t.uleb128 %d\n",
3969 64+i, cf-i-4); 3971 64+i, i+(3+(28-19+1)-8));
3970 fprintf(ctx->fp, 3972 fprintf(ctx->fp,
3971 "\t.align 3\n" 3973 "\t.align 3\n"
3972 ".LEFDE0:\n\n"); 3974 ".LEFDE0:\n\n");
@@ -3979,9 +3981,11 @@ static void emit_asm_debug(BuildCtx *ctx)
3979 "\t.quad lj_vm_ffi_call\n" 3981 "\t.quad lj_vm_ffi_call\n"
3980 "\t.quad %d\n" 3982 "\t.quad %d\n"
3981 "\t.byte 0xe\n\t.uleb128 32\n" /* def_cfa_offset */ 3983 "\t.byte 0xe\n\t.uleb128 32\n" /* def_cfa_offset */
3982 "\t.byte 0x9d\n\t.uleb128 4\n" /* offset fp */ 3984 "\t.byte 0x9e\n\t.uleb128 1\n" /* offset lr */
3983 "\t.byte 0x9e\n\t.uleb128 3\n" /* offset lr */ 3985 "\t.byte 0x9d\n\t.uleb128 2\n" /* offset fp */
3984 "\t.byte 0x93\n\t.uleb128 2\n" /* offset x19 */ 3986 "\t.byte 0x93\n\t.uleb128 3\n" /* offset x19 */
3987 "\t.byte 0x94\n\t.uleb128 4\n" /* offset x20 */
3988 "\t.byte 0xd\n\t.uleb128 0x1d\n" /* def_cfa_register fp */
3985 "\t.align 3\n" 3989 "\t.align 3\n"
3986 ".LEFDE1:\n\n", (int)ctx->codesz - fcofs); 3990 ".LEFDE1:\n\n", (int)ctx->codesz - fcofs);
3987#endif 3991#endif
@@ -4012,14 +4016,14 @@ static void emit_asm_debug(BuildCtx *ctx)
4012 "\t.long %d\n" 4016 "\t.long %d\n"
4013 "\t.uleb128 0\n" /* augmentation length */ 4017 "\t.uleb128 0\n" /* augmentation length */
4014 "\t.byte 0xe\n\t.uleb128 %d\n" /* def_cfa_offset */ 4018 "\t.byte 0xe\n\t.uleb128 %d\n" /* def_cfa_offset */
4015 "\t.byte 0x9d\n\t.uleb128 %d\n" /* offset fp */ 4019 "\t.byte 0x9e\n\t.uleb128 1\n" /* offset lr */
4016 "\t.byte 0x9e\n\t.uleb128 %d\n", /* offset lr */ 4020 "\t.byte 0x9d\n\t.uleb128 2\n", /* offset fp */
4017 fcofs, CFRAME_SIZE, cf, cf-1); 4021 fcofs, CFRAME_SIZE);
4018 for (i = 19; i <= 28; i++) /* offset x19-x28 */ 4022 for (i = 19; i <= 28; i++) /* offset x19-x28 */
4019 fprintf(ctx->fp, "\t.byte 0x%x\n\t.uleb128 %d\n", 0x80+i, cf-i+17); 4023 fprintf(ctx->fp, "\t.byte 0x%x\n\t.uleb128 %d\n", 0x80+i, i+(3-19));
4020 for (i = 8; i <= 15; i++) /* offset d8-d15 */ 4024 for (i = 8; i <= 15; i++) /* offset d8-d15 */
4021 fprintf(ctx->fp, "\t.byte 5\n\t.uleb128 0x%x\n\t.uleb128 %d\n", 4025 fprintf(ctx->fp, "\t.byte 5\n\t.uleb128 0x%x\n\t.uleb128 %d\n",
4022 64+i, cf-i-4); 4026 64+i, i+(3+(28-19+1)-8));
4023 fprintf(ctx->fp, 4027 fprintf(ctx->fp,
4024 "\t.align 3\n" 4028 "\t.align 3\n"
4025 ".LEFDE2:\n\n"); 4029 ".LEFDE2:\n\n");
@@ -4048,13 +4052,112 @@ static void emit_asm_debug(BuildCtx *ctx)
4048 "\t.long %d\n" 4052 "\t.long %d\n"
4049 "\t.uleb128 0\n" /* augmentation length */ 4053 "\t.uleb128 0\n" /* augmentation length */
4050 "\t.byte 0xe\n\t.uleb128 32\n" /* def_cfa_offset */ 4054 "\t.byte 0xe\n\t.uleb128 32\n" /* def_cfa_offset */
4051 "\t.byte 0x9d\n\t.uleb128 4\n" /* offset fp */ 4055 "\t.byte 0x9e\n\t.uleb128 1\n" /* offset lr */
4052 "\t.byte 0x9e\n\t.uleb128 3\n" /* offset lr */ 4056 "\t.byte 0x9d\n\t.uleb128 2\n" /* offset fp */
4053 "\t.byte 0x93\n\t.uleb128 2\n" /* offset x19 */ 4057 "\t.byte 0x93\n\t.uleb128 3\n" /* offset x19 */
4058 "\t.byte 0x94\n\t.uleb128 4\n" /* offset x20 */
4059 "\t.byte 0xd\n\t.uleb128 0x1d\n" /* def_cfa_register fp */
4054 "\t.align 3\n" 4060 "\t.align 3\n"
4055 ".LEFDE3:\n\n", (int)ctx->codesz - fcofs); 4061 ".LEFDE3:\n\n", (int)ctx->codesz - fcofs);
4056#endif 4062#endif
4057 break; 4063 break;
4064#if !LJ_NO_UNWIND
4065 case BUILD_machasm: {
4066#if LJ_HASFFI
4067 int fcsize = 0;
4068#endif
4069 int j;
4070 fprintf(ctx->fp, "\t.section __TEXT,__eh_frame,coalesced,no_toc+strip_static_syms+live_support\n");
4071 fprintf(ctx->fp,
4072 "EH_frame1:\n"
4073 "\t.set L$set$x,LECIEX-LSCIEX\n"
4074 "\t.long L$set$x\n"
4075 "LSCIEX:\n"
4076 "\t.long 0\n"
4077 "\t.byte 0x1\n"
4078 "\t.ascii \"zPR\\0\"\n"
4079 "\t.byte 0x1\n"
4080 "\t.byte 128-8\n"
4081 "\t.byte 30\n" /* Return address is in lr. */
4082 "\t.byte 6\n" /* augmentation length */
4083 "\t.byte 0x9b\n" /* indirect|pcrel|sdata4 */
4084 "\t.long _lj_err_unwind_dwarf@GOTPCREL\n"
4085 "\t.byte 0x1b\n" /* pcrel|sdata4 */
4086 "\t.byte 0xc\n\t.byte 31\n\t.byte 0\n" /* def_cfa sp */
4087 "\t.align 3\n"
4088 "LECIEX:\n\n");
4089 for (j = 0; j < ctx->nsym; j++) {
4090 const char *name = ctx->sym[j].name;
4091 int32_t size = ctx->sym[j+1].ofs - ctx->sym[j].ofs;
4092 if (size == 0) continue;
4093#if LJ_HASFFI
4094 if (!strcmp(name, "_lj_vm_ffi_call")) { fcsize = size; continue; }
4095#endif
4096 fprintf(ctx->fp,
4097 "%s.eh:\n"
4098 "LSFDE%d:\n"
4099 "\t.set L$set$%d,LEFDE%d-LASFDE%d\n"
4100 "\t.long L$set$%d\n"
4101 "LASFDE%d:\n"
4102 "\t.long LASFDE%d-EH_frame1\n"
4103 "\t.long %s-.\n"
4104 "\t.long %d\n"
4105 "\t.byte 0\n" /* augmentation length */
4106 "\t.byte 0xe\n\t.byte %d\n\t.byte 1\n" /* def_cfa_offset */
4107 "\t.byte 0x9e\n\t.byte 1\n" /* offset lr */
4108 "\t.byte 0x9d\n\t.byte 2\n", /* offset fp */
4109 name, j, j, j, j, j, j, j, name, size, CFRAME_SIZE);
4110 for (i = 19; i <= 28; i++) /* offset x19-x28 */
4111 fprintf(ctx->fp, "\t.byte 0x%x\n\t.byte %d\n", 0x80+i, i+(3-19));
4112 for (i = 8; i <= 15; i++) /* offset d8-d15 */
4113 fprintf(ctx->fp, "\t.byte 5\n\t.byte 0x%x\n\t.byte %d\n",
4114 64+i, i+(3+(28-19+1)-8));
4115 fprintf(ctx->fp,
4116 "\t.align 3\n"
4117 "LEFDE%d:\n\n", j);
4118 }
4119#if LJ_HASFFI
4120 if (fcsize) {
4121 fprintf(ctx->fp,
4122 "EH_frame2:\n"
4123 "\t.set L$set$y,LECIEY-LSCIEY\n"
4124 "\t.long L$set$y\n"
4125 "LSCIEY:\n"
4126 "\t.long 0\n"
4127 "\t.byte 0x1\n"
4128 "\t.ascii \"zR\\0\"\n"
4129 "\t.byte 0x1\n"
4130 "\t.byte 128-8\n"
4131 "\t.byte 30\n" /* Return address is in lr. */
4132 "\t.byte 1\n" /* augmentation length */
4133 "\t.byte 0x1b\n" /* pcrel|sdata4 */
4134 "\t.byte 0xc\n\t.byte 31\n\t.byte 0\n" /* def_cfa sp */
4135 "\t.align 3\n"
4136 "LECIEY:\n\n");
4137 fprintf(ctx->fp,
4138 "_lj_vm_ffi_call.eh:\n"
4139 "LSFDEY:\n"
4140 "\t.set L$set$yy,LEFDEY-LASFDEY\n"
4141 "\t.long L$set$yy\n"
4142 "LASFDEY:\n"
4143 "\t.long LASFDEY-EH_frame2\n"
4144 "\t.long _lj_vm_ffi_call-.\n"
4145 "\t.long %d\n"
4146 "\t.byte 0\n" /* augmentation length */
4147 "\t.byte 0xe\n\t.byte 32\n" /* def_cfa_offset */
4148 "\t.byte 0x9e\n\t.byte 1\n" /* offset lr */
4149 "\t.byte 0x9d\n\t.byte 2\n" /* offset fp */
4150 "\t.byte 0x93\n\t.byte 3\n" /* offset x19 */
4151 "\t.byte 0x94\n\t.byte 4\n" /* offset x20 */
4152 "\t.byte 0xd\n\t.uleb128 0x1d\n" /* def_cfa_register fp */
4153 "\t.align 3\n"
4154 "LEFDEY:\n\n", fcsize);
4155 }
4156#endif
4157 fprintf(ctx->fp, ".subsections_via_symbols\n");
4158 }
4159 break;
4160#endif
4058 default: 4161 default:
4059 break; 4162 break;
4060 } 4163 }