On arm and arm64, the setjmp/longjmp implementations (in both msvcrt.dll and ucrtbase.dll) require binaries to have proper SEH information. On arm, we can get around this by passing NULL as the frame/ctx parameter to _setjmp, but that doesn't work on arm64.
Work around it by providing a custom implementation of the functions in libmingwex instead. Signed-off-by: Martin Storsjö <mar...@martin.st> --- mingw-w64-crt/misc/mingw_getsp.S | 99 ++++++++++++++++++++++++++++++++++++++++ mingw-w64-headers/crt/setjmp.h | 4 ++ 2 files changed, 103 insertions(+) diff --git a/mingw-w64-crt/misc/mingw_getsp.S b/mingw-w64-crt/misc/mingw_getsp.S index 97510c8..5d224d1 100644 --- a/mingw-w64-crt/misc/mingw_getsp.S +++ b/mingw-w64-crt/misc/mingw_getsp.S @@ -51,3 +51,102 @@ __MINGW_USYMBOL(longjmp): jmp *__imp__longjmp #endif #endif /* !(defined(_ARM_) || defined(__arm__)) */ + +#if defined(_ARM_) || defined(__arm__) || defined(_ARM64_) || defined(__aarch64__) + .globl __MINGW_USYMBOL(__mingw_setjmp) + .def __MINGW_USYMBOL(__mingw_setjmp); .scl 2; .type 32; .endef +__MINGW_USYMBOL(__mingw_setjmp): +#if defined(_ARM_) || defined(__arm__) + mov r1, #0 + str r1, [r0] /* jmp_buf->Frame */ + str r4, [r0, #0x4] /* jmp_buf->R4 */ + str r5, [r0, #0x8] /* jmp_buf->R5 */ + str r6, [r0, #0xc] /* jmp_buf->R6 */ + str r7, [r0, #0x10] /* jmp_buf->R7 */ + str r8, [r0, #0x14] /* jmp_buf->R8 */ + str r9, [r0, #0x18] /* jmp_buf->R9 */ + str r10, [r0, #0x1c] /* jmp_buf->R10 */ + str r11, [r0, #0x20] /* jmp_buf->R11 */ + str sp, [r0, #0x24] /* jmp_buf->Sp */ + str lr, [r0, #0x28] /* jmp_buf->Pc */ + vmrs r2, fpscr + str r2, [r0, #0x2c] /* jmp_buf->Fpscr */ + vstr d8, [r0, #0x30] /* jmp_buf->D[0] */ + vstr d9, [r0, #0x38] /* jmp_buf->D[1] */ + vstr d10, [r0, #0x40] /* jmp_buf->D[2] */ + vstr d11, [r0, #0x48] /* jmp_buf->D[3] */ + vstr d12, [r0, #0x50] /* jmp_buf->D[4] */ + vstr d13, [r0, #0x58] /* jmp_buf->D[5] */ + vstr d14, [r0, #0x60] /* jmp_buf->D[6] */ + vstr d15, [r0, #0x68] /* jmp_buf->D[7] */ + mov r0, #0 + bx lr +#elif defined(_ARM64_) || defined(__aarch64__) + str xzr, [x0] /* jmp_buf->Frame */ + stp x19, x20, [x0, #0x10] /* jmp_buf->X19, X20 */ + stp x21, x22, [x0, #0x20] /* jmp_buf->X21, X22 */ + stp x23, x24, [x0, #0x30] /* jmp_buf->X23, X24 */ + stp x25, x26, [x0, #0x40] /* jmp_buf->X25, X26 */ + stp x27, x28, [x0, #0x50] /* jmp_buf->X27, X28 */ + stp x29, x30, [x0, #0x60] /* jmp_buf->Fp, Lr */ + mov x2, sp + str x2, [x0, #0x70] /* jmp_buf->Sp */ + mrs x2, fpcr + str w2, [x0, #0x78] /* jmp_buf->Fpcr */ + mrs x2, fpsr + str w2, [x0, #0x7c] /* jmp_buf->Fpsr */ + stp d8, d9, [x0, #0x80] /* jmp_buf->D[0-1] */ + stp d10, d11, [x0, #0x90] /* jmp_buf->D[2-3] */ + stp d12, d13, [x0, #0xa0] /* jmp_buf->D[4-5] */ + stp d14, d15, [x0, #0xb0] /* jmp_buf->D[6-7] */ + mov x0, #0 + ret +#endif + + .globl __MINGW_USYMBOL(__mingw_longjmp) + .def __MINGW_USYMBOL(__mingw_longjmp); .scl 2; .type 32; .endef +__MINGW_USYMBOL(__mingw_longjmp): +#if defined(_ARM_) || defined(__arm__) + ldr r4, [r0, #0x4] /* jmp_buf->R4 */ + ldr r5, [r0, #0x8] /* jmp_buf->R5 */ + ldr r6, [r0, #0xc] /* jmp_buf->R6 */ + ldr r7, [r0, #0x10] /* jmp_buf->R7 */ + ldr r8, [r0, #0x14] /* jmp_buf->R8 */ + ldr r9, [r0, #0x18] /* jmp_buf->R9 */ + ldr r10, [r0, #0x1c] /* jmp_buf->R10 */ + ldr r11, [r0, #0x20] /* jmp_buf->R11 */ + ldr sp, [r0, #0x24] /* jmp_buf->Sp */ + ldr r2, [r0, #0x28] /* jmp_buf->Pc */ + ldr r3, [r0, #0x2c] /* jmp_buf->Fpscr */ + vmsr fpscr, r3 + vldr d8, [r0, #0x30] /* jmp_buf->D[0] */ + vldr d9, [r0, #0x38] /* jmp_buf->D[1] */ + vldr d10, [r0, #0x40] /* jmp_buf->D[2] */ + vldr d11, [r0, #0x48] /* jmp_buf->D[3] */ + vldr d12, [r0, #0x50] /* jmp_buf->D[4] */ + vldr d13, [r0, #0x58] /* jmp_buf->D[5] */ + vldr d14, [r0, #0x60] /* jmp_buf->D[6] */ + vldr d15, [r0, #0x68] /* jmp_buf->D[7] */ + mov r0, r1 /* retval */ + bx r2 +#elif defined(_ARM64_) || defined(__aarch64__) + ldp x19, x20, [x0, #0x10] /* jmp_buf->X19, X20 */ + ldp x21, x22, [x0, #0x20] /* jmp_buf->X21, X22 */ + ldp x23, x24, [x0, #0x30] /* jmp_buf->X23, X24 */ + ldp x25, x26, [x0, #0x40] /* jmp_buf->X25, X26 */ + ldp x27, x28, [x0, #0x50] /* jmp_buf->X27, X28 */ + ldp x29, x30, [x0, #0x60] /* jmp_buf->Fp, Lr */ + ldr x2, [x0, #0x70] /* jmp_buf->Sp */ + mov sp, x2 + ldr w2, [x0, #0x78] /* jmp_buf->Fpcr */ + msr fpcr, x2 + ldr w2, [x0, #0x7c] /* jmp_buf->Fpsr */ + msr fpsr, x2 + ldp d8, d9, [x0, #0x80] /* jmp_buf->D[0-1] */ + ldp d10, d11, [x0, #0x90] /* jmp_buf->D[2-3] */ + ldp d12, d13, [x0, #0xa0] /* jmp_buf->D[4-5] */ + ldp d14, d15, [x0, #0xb0] /* jmp_buf->D[6-7] */ + mov x0, x1 /* retval */ + ret +#endif +#endif diff --git a/mingw-w64-headers/crt/setjmp.h b/mingw-w64-headers/crt/setjmp.h index ec4b013..fc79f10 100644 --- a/mingw-w64-headers/crt/setjmp.h +++ b/mingw-w64-headers/crt/setjmp.h @@ -213,6 +213,10 @@ void * __cdecl __attribute__ ((__nothrow__)) mingw_getsp (void); # ifndef _INC_SETJMPEX # if defined(_X86_) || defined(__i386__) # define setjmp(BUF) _setjmp3((BUF), NULL) +# elif defined(_ARM_) || defined(__arm__) || defined(_ARM64_) || defined(__aarch64__) +# define setjmp(BUF) __mingw_setjmp((BUF)) +# define longjmp __mingw_longjmp + int __cdecl __attribute__ ((__nothrow__,__returns_twice__)) __mingw_setjmp(jmp_buf _Buf); # else # if (__MINGW_GCC_VERSION < 40702) # define setjmp(BUF) _setjmp((BUF), mingw_getsp()) -- 2.7.4 ------------------------------------------------------------------------------ Check out the vibrant tech community on one of the world's most engaging tech sites, Slashdot.org! http://sdm.link/slashdot _______________________________________________ Mingw-w64-public mailing list Mingw-w64-public@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/mingw-w64-public