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

This commit is contained in:
Mike Pall 2011-03-17 16:05:04 +01:00
parent 6299485000
commit ac3b1dcfc5
6 changed files with 3369 additions and 3341 deletions

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -530,6 +530,14 @@ static void build_subroutines(BuildCtx *ctx, int cmov, int sse)
| mov dword GL:RB->vmstate, ~LJ_VMST_C | mov dword GL:RB->vmstate, ~LJ_VMST_C
| jmp ->vm_leave_unw | 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. |->vm_unwind_ff@4: // Unwind C stack, return from ff pcall.
| // (void *cframe) | // (void *cframe)
|.if X64 |.if X64

File diff suppressed because it is too large Load Diff

View File

@ -577,6 +577,16 @@ LJ_FUNCA int lj_err_unwind_dwarf(int version, _Unwind_Action actions,
lj_vm_unwind_c_eh)); lj_vm_unwind_c_eh));
return _URC_INSTALL_CONTEXT; 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 #else
/* This is not the proper way to escape from the unwinder. We get away with /* 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. ** it on x86/PPC because the interpreter restores all callee-saved regs.

View File

@ -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_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_c_eh(void);
LJ_ASMF void lj_vm_unwind_ff_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. */ /* Miscellaneous functions. */
#if LJ_TARGET_X86ORX64 #if LJ_TARGET_X86ORX64