On Thu, 12 Apr 2018, André Hentschel wrote:

Am 11.04.2018 um 22:38 schrieb Martin Storsjö:
Hi André,

Can you review this patch I sent to mingw-w64 yesterday? (I don't think many 
others are going to give it much comments.)

The arm32 implementation is based on your code from wine (I hope that's ok with 
you license-wise), while the arm64 one, also from wine, is one that I wrote.

// Martin

---------- Forwarded message ----------
Date: Tue, 10 Apr 2018 22:52:03 +0300
From: Martin Storsjö <mar...@martin.st>
To: mingw-w64-public@lists.sourceforge.net
Cc: Martin Storsjö <mar...@martin.st>
Subject: [PATCH] setjmp: Provide a manual implementation for arm and arm64

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())


Hi Martin,

Patch looks good, though license wise I'd like to be asked and mentioned when 
moving my code into public domain.
Now that you asked me, I'll solve the mentioning issue by providing my sign-off 
below in the hope it'll land in the git commit.
(Maybe resend your patch to be sure)

Thanks - and sorry abut that, I should of course asked before sending the patch.

I'll resend the patch with an updated commit message.

// Martin
------------------------------------------------------------------------------
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

Reply via email to