Ver código fonte

x64: Workaround for libgcc unwind bug (still present in RHEL 5.5).

Mike Pall 14 anos atrás
pai
commit
ac3b1dcfc5
6 arquivos alterados com 1072 adições e 1050 exclusões
  1. 359 358
      src/buildvm_x64.h
  2. 340 340
      src/buildvm_x64win.h
  3. 8 0
      src/buildvm_x86.dasc
  4. 352 352
      src/buildvm_x86.h
  5. 10 0
      src/lj_err.c
  6. 3 0
      src/lj_vm.h

Diferenças do arquivo suprimidas por serem muito extensas
+ 359 - 358
src/buildvm_x64.h


Diferenças do arquivo suprimidas por serem muito extensas
+ 340 - 340
src/buildvm_x64win.h


+ 8 - 0
src/buildvm_x86.dasc

@@ -530,6 +530,14 @@ static void build_subroutines(BuildCtx *ctx, int cmov, int sse)
   |  mov dword GL:RB->vmstate, ~LJ_VMST_C
   |  jmp ->vm_leave_unw
   |
+  |->vm_unwind_rethrow:
+  |.if X64 and not X64WIN
+  |  mov FCARG1, SAVE_L
+  |  mov FCARG2, eax
+  |  restoreregs
+  |  jmp extern lj_err_throw@8		// (lua_State *L, int errcode)
+  |.endif
+  |
   |->vm_unwind_ff@4:			// Unwind C stack, return from ff pcall.
   |  // (void *cframe)
   |.if X64

Diferenças do arquivo suprimidas por serem muito extensas
+ 352 - 352
src/buildvm_x86.h


+ 10 - 0
src/lj_err.c

@@ -577,6 +577,16 @@ LJ_FUNCA int lj_err_unwind_dwarf(int version, _Unwind_Action actions,
 				       lj_vm_unwind_c_eh));
       return _URC_INSTALL_CONTEXT;
     }
+#if LJ_TARGET_X86ORX64
+    else if ((actions & _UA_HANDLER_FRAME)) {
+      /* Workaround for ancient libgcc bug. Still present in RHEL 5.5. :-/
+      ** Real fix: http://gcc.gnu.org/viewcvs/trunk/gcc/unwind-dw2.c?r1=121165&r2=124837&pathrev=153877&diff_format=h
+      */
+      _Unwind_SetGR(ctx, LJ_TARGET_EHRETREG, errcode);
+      _Unwind_SetIP(ctx, (_Unwind_Ptr)lj_vm_unwind_rethrow);
+      return _URC_INSTALL_CONTEXT;
+    }
+#endif
 #else
     /* This is not the proper way to escape from the unwinder. We get away with
     ** it on x86/PPC because the interpreter restores all callee-saved regs.

+ 3 - 0
src/lj_vm.h

@@ -19,6 +19,9 @@ LJ_ASMF_NORET void LJ_FASTCALL lj_vm_unwind_c(void *cframe, int errcode);
 LJ_ASMF_NORET void LJ_FASTCALL lj_vm_unwind_ff(void *cframe);
 LJ_ASMF void lj_vm_unwind_c_eh(void);
 LJ_ASMF void lj_vm_unwind_ff_eh(void);
+#if LJ_TARGET_X86ORX64
+LJ_ASMF void lj_vm_unwind_rethrow(void);
+#endif
 
 /* Miscellaneous functions. */
 #if LJ_TARGET_X86ORX64

Alguns arquivos não foram mostrados porque muitos arquivos mudaram nesse diff