]> git.ipfire.org Git - thirdparty/LuaJIT.git/commitdiff
Windows/ARM64: Fix exception unwinding.
authorMike Pall <mike>
Mon, 11 Sep 2023 11:33:27 +0000 (13:33 +0200)
committerMike Pall <mike>
Mon, 11 Sep 2023 11:33:27 +0000 (13:33 +0200)
Thanks to Peter Cawley. #593

src/host/buildvm_peobj.c
src/lj_err.c

index fc3ef71ae84d563c5c6e653825252b91a5dff5b9..cdbb79b627532425b41cee483ad366b6626f6ed0 100644 (file)
@@ -354,7 +354,7 @@ void emit_peobj(BuildCtx *ctx)
 #define CBE16(x)       (*p = ((x) >> 8) & 0xff, p[1] = (x) & 0xff, p += 2)
 #define CALLOC_S(s)    (*p++ = ((s) >> 4))  /* s < 512 */
 #define CSAVE_FPLR(o)  (*p++ = 0x40 | ((o) >> 3))  /* o <= 504 */
-#define CSAVE_REGP(r,o)        CBE16(0xc800 | (((r)-19)<< 6) | ((o) >> 3))
+#define CSAVE_REGP(r,o)        CBE16(0xc800 | (((r) - 19) << 6) | ((o) >> 3))
 #define CSAVE_REGS(r1,r2,o1) do { \
   int r, o; for (r = r1, o = o1; r <= r2; r += 2, o -= 16) CSAVE_REGP(r, o); \
 } while (0)
@@ -362,6 +362,7 @@ void emit_peobj(BuildCtx *ctx)
 #define CSAVE_FREGS(r1,r2,o1) do { \
   int r, o; for (r = r1, o = o1; r <= r2; r += 2, o -= 16) CSAVE_FREGP(r, o); \
 } while (0)
+#define CSAVE_REG(r,o) CBE16(0xd000 | (((r) - 19) << 6) | (~(o) >> 3))
 #define CSAVE_REGX(r,o)        CBE16(0xd400 | (((r) - 19) << 5) | (~(o) >> 3))
 #define CADD_FP(s)     CBE16(0xe200 | ((s) >> 3))  /* s < 8*256 */
 #define CODE_NOP       0xe3
@@ -373,12 +374,11 @@ void emit_peobj(BuildCtx *ctx)
 
     /* Unwind codes for .text section with handler. */
     p = uwc;
-    CALLOC_S(208);             /* +1 */
-    CSAVE_FPLR(192);           /* +1 */
-    CADD_FP(192);              /* +2 */
     CSAVE_REGS(19, 28, 184);   /* +5*2 */
     CSAVE_FREGS(8, 15, 104);   /* +4*2 */
-    CEND_ALIGN;                        /* +1 +1 -> 24 */
+    CSAVE_FPLR(192);           /* +1 */
+    CALLOC_S(208);             /* +1 */
+    CEND_ALIGN;                        /* +1 +3 -> 24 */
 
     u32 = ((24u >> 2) << 27) | (1u << 20) | (fcofs >> 2);
     owrite(ctx, &u32, 4);
@@ -389,9 +389,9 @@ void emit_peobj(BuildCtx *ctx)
 
     /* Unwind codes for vm_ffi_call without handler. */
     p = uwc;
-    CSAVE_FPLR(16);            /* +1 */
     CADD_FP(16);               /* +2 */
-    CSAVE_REGX(19, -24);       /* +2 */
+    CSAVE_FPLR(16);            /* +1 */
+    CSAVE_REG(19, 8);          /* +2 */
     CSAVE_REGX(20, -32);       /* +2 */
     CEND_ALIGN;                        /* +1 +0 -> 8 */
 
index 6e50cbee3bae814d7a01a470f70c3f1a203cc11c..8ef51bf2b8012733478c225433c279100a5e8248 100644 (file)
@@ -261,6 +261,8 @@ LJ_FUNCA int lj_err_unwind_win(EXCEPTION_RECORD *rec,
 {
 #if LJ_TARGET_X86
   void *cf = (char *)f - CFRAME_OFS_SEH;
+#elif LJ_TARGET_ARM64
+  void *cf = (char *)f - CFRAME_SIZE;
 #else
   void *cf = f;
 #endif
@@ -297,11 +299,11 @@ LJ_FUNCA int lj_err_unwind_win(EXCEPTION_RECORD *rec,
 #else
       /* Unwind the stack and call all handlers for all lower C frames
       ** (including ourselves) again with EH_UNWINDING set. Then set
-      ** stack pointer = cf, result = errcode and jump to the specified target.
+      ** stack pointer = f, result = errcode and jump to the specified target.
       */
-      RtlUnwindEx(cf, (void *)((cframe_unwind_ff(cf2) && errcode != LUA_YIELD) ?
-                              lj_vm_unwind_ff_eh :
-                              lj_vm_unwind_c_eh),
+      RtlUnwindEx(f, (void *)((cframe_unwind_ff(cf2) && errcode != LUA_YIELD) ?
+                             lj_vm_unwind_ff_eh :
+                             lj_vm_unwind_c_eh),
                  rec, (void *)(uintptr_t)errcode, ctx, dispatch->HistoryTable);
       /* RtlUnwindEx should never return. */
 #endif