On 7/12/22, LIU Hao <lh_mo...@126.com> wrote: > 在 2022/7/12 09:18, Ozkan Sezer 写道: >> I hit this curiosity when I built quakespasm [1] for x64 using gcc-7.5.0 >> against mingw-w64 v5.x branch: Hitting longjmp crashes when built using >> -fno-asynchronous-unwind-tables gcc switch but works properly without it. >> Anyone has any insight into this? (And yes I know that the v5.x branch is >> old but the toolchain has been available.) >> > > Is it because that `longjmp()` unwinds the stack on Windows x64, but not on > x86 or other operating > systems? >
My toolchain is a SEH one, and -fno-asynchronous-unwind-tables inhibits defining of the __SEH__ macro apparently. v7.x seems to improve on the matter, ie. the following three patches' backport _should_ do the trick, the last two seems to be the key: https://sourceforge.net/p/mingw-w64/mingw-w64/ci/02390fa9c1dd6d3870fa5f5f1b0cf702f1267362/ https://sourceforge.net/p/mingw-w64/mingw-w64/ci/436ad4b83035937125e8e596893269ff4f1fe662/ https://sourceforge.net/p/mingw-w64/mingw-w64/ci/844cb490ab2cc32ac3df5914700564b2e40739d8/ Is the attached patch against v5.x correct? (haven't tested yet..) -- O.S.
diff --git a/mingw-w64-crt/def-include/msvcrt-common.def.in b/mingw-w64-crt/def-include/msvcrt-common.def.in index 76e1fa3..a27fd22 100644 --- a/mingw-w64-crt/def-include/msvcrt-common.def.in +++ b/mingw-w64-crt/def-include/msvcrt-common.def.in @@ -125,11 +125,11 @@ ADD_UNDERSCORE(hypot) ;logb ADD_UNDERSCORE(nextafter) +longjmp + _daylight DATA _timezone DATA _tzname DATA ADD_UNDERSCORE(daylight) ADD_UNDERSCORE(timezone) ADD_UNDERSCORE(tzname) - -longjmp DATA diff --git a/mingw-w64-crt/lib32/crtdll.def b/mingw-w64-crt/lib32/crtdll.def index 1c73001..38e300a 100644 --- a/mingw-w64-crt/lib32/crtdll.def +++ b/mingw-w64-crt/lib32/crtdll.def @@ -598,7 +598,7 @@ localtime DATA ;_localtime32 = localtime log log10 -longjmp DATA +longjmp malloc mblen mbstowcs diff --git a/mingw-w64-crt/lib64/ntdll.def b/mingw-w64-crt/lib64/ntdll.def index cc81a06..d08f498 100644 --- a/mingw-w64-crt/lib64/ntdll.def +++ b/mingw-w64-crt/lib64/ntdll.def @@ -1963,7 +1963,7 @@ iswxdigit isxdigit labs log -longjmp DATA +longjmp mbstowcs memchr memcmp diff --git a/mingw-w64-crt/misc/mingw_getsp.S b/mingw-w64-crt/misc/mingw_getsp.S index 3c99658..7992abd 100644 --- a/mingw-w64-crt/misc/mingw_getsp.S +++ b/mingw-w64-crt/misc/mingw_getsp.S @@ -25,26 +25,3 @@ __MINGW_USYMBOL(mingw_getsp): mov r0, sp bx lr #endif - -/* On ARM: - * Error: cannot represent BFD_RELOC_32_PCREL relocation in this object file format - * But anyway, nothing is needed here as libarm32/libmsvcrt.a is exporting longjmp - ldr ip, 1f - ldr pc, [pc, ip] - 1: .long __imp_longjmp - (1b + 4) -*/ -#if !(defined(_ARM_) || defined(__arm__)) - .globl __MINGW_USYMBOL(longjmp) - .def __MINGW_USYMBOL(longjmp); .scl 2; .type 32; .endef -__MINGW_USYMBOL(longjmp): -#if defined(_AMD64_) || defined(__x86_64__) -#ifndef __SEH__ - xorq %rax,%rax - movq %rax, (%rcx) -#endif - leaq __MINGW_IMP_LSYMBOL(longjmp)(%rip), %rax - jmpq *(%rax) -#elif defined(_X86_) || defined(__i386__) - jmp *__imp__longjmp -#endif -#endif /* !(defined(_ARM_) || defined(__arm__)) */ diff --git a/mingw-w64-headers/crt/setjmp.h b/mingw-w64-headers/crt/setjmp.h index 5be566d..d116bd4 100644 --- a/mingw-w64-headers/crt/setjmp.h +++ b/mingw-w64-headers/crt/setjmp.h @@ -169,24 +169,28 @@ extern "C" { #define _JMP_BUF_DEFINED #endif +_CRTIMP __MINGW_ATTRIB_NORETURN __attribute__ ((__nothrow__)) void __cdecl longjmp(jmp_buf _Buf,int _Value); + void * __cdecl __attribute__ ((__nothrow__)) mingw_getsp (void); #ifndef USE_NO_MINGW_SETJMP_TWO_ARGS # ifndef _INC_SETJMPEX -# ifdef _WIN64 +# if defined(_X86_) || defined(__i386__) +# define setjmp(BUF) _setjmp3((BUF), NULL) +# elif defined(__SEH__) # if (__MINGW_GCC_VERSION < 40702) # define setjmp(BUF) _setjmp((BUF), mingw_getsp()) # else # define setjmp(BUF) _setjmp((BUF), __builtin_frame_address (0)) # endif # else -# define setjmp(BUF) _setjmp3((BUF), NULL) +# define setjmp(BUF) _setjmp((BUF), NULL) # endif int __cdecl __attribute__ ((__nothrow__,__returns_twice__)) _setjmp(jmp_buf _Buf, void *_Ctx); int __cdecl __attribute__ ((__nothrow__,__returns_twice__)) _setjmp3(jmp_buf _Buf, void *_Ctx); # else # undef setjmp -# ifdef _WIN64 +# ifdef __SEH__ # if (__MINGW_GCC_VERSION < 40702) # define setjmp(BUF) _setjmpex((BUF), mingw_getsp()) # define setjmpex(BUF) _setjmpex((BUF), mingw_getsp()) @@ -210,9 +214,6 @@ void * __cdecl __attribute__ ((__nothrow__)) mingw_getsp (void); int __cdecl __attribute__ ((__nothrow__,__returns_twice__)) setjmp(jmp_buf _Buf); #endif - __declspec(noreturn) __attribute__ ((__nothrow__)) void __cdecl ms_longjmp(jmp_buf _Buf,int _Value)/* throw(...)*/; - __declspec(noreturn) __attribute__ ((__nothrow__)) void __cdecl longjmp(jmp_buf _Buf,int _Value); - #ifdef __cplusplus } #endif
_______________________________________________ Mingw-w64-public mailing list Mingw-w64-public@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/mingw-w64-public