On Tue, 7 Mar 2023, Martin Storsjö wrote:

By default, setjmp/longjmp in the MS CRTs use SEH unwinding to
reach the destination stack frame, on platforms that use SEH.

On x86_64, the lower level functions allow opting out from this
behaviour by passing NULL instead of the target stack frame. On
arm and aarch64 though, the UCRT and msvcrt.dll implementations of
setjmp only support SEH based unwinding.

Before the mingw toolchains supported SEH on arm and aarch64, we
used a local reimplementation of the functions that don't unwind
at all, just restore the register context.

Add an option of choosing to not do unwinding with SEH. This is
necessary for e.g. QEMU, where unwinding through generated code
doesn't work (as there's no corresponding unwind info generated).

So far, QEMU has manually worked around the issue by redefining
setjmp, but with this option, they could just set the define
instead.

For x86_64, this resorts to calling _setjmp with the second parameter
set to NULL. For arm and aarch64, it means calling our own
__mingw_setjmp/__mingw_longjmp instead.

Signed-off-by: Martin Storsjö <[email protected]>
---
mingw-w64-headers/crt/setjmp.h | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/mingw-w64-headers/crt/setjmp.h b/mingw-w64-headers/crt/setjmp.h
index 5c139fff5..454a32ed0 100644
--- a/mingw-w64-headers/crt/setjmp.h
+++ b/mingw-w64-headers/crt/setjmp.h
@@ -225,12 +225,12 @@ 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__)) && (!defined(__SEH__) || 
!__has_builtin(__builtin_sponentry)))
+#    elif ((defined(_ARM_) || defined(__arm__) || defined(_ARM64_) || 
defined(__aarch64__)) && (!defined(__SEH__) || 
!__has_builtin(__builtin_sponentry) || defined(USE_NO_MINGW_SETJMP_SEH)))
#      define setjmp(BUF) __mingw_setjmp((BUF))
#      define longjmp __mingw_longjmp
  int __cdecl __attribute__ ((__nothrow__,__returns_twice__)) 
__mingw_setjmp(jmp_buf _Buf);
  __MINGW_ATTRIB_NORETURN __attribute__ ((__nothrow__)) void 
__mingw_longjmp(jmp_buf _Buf,int _Value);
-#    elif defined(__SEH__)
+#    elif defined(__SEH__) && !defined(USE_NO_MINGW_SETJMP_SEH)

I forgot to a comment to the patch - I'm open for suggestions for a better name to use for the define we check here. Should we use a user space define name like this, or one prepended with two underscores (like __USE_MINGW_ANSI_STDIO)?

(This file already checks a define named USE_NO_MINGW_SETJMP_TWO_ARGS - although I'm not sure if the codepaths used by that actually have been tested and work in the last decade, on modern architectures.)

// Martin

_______________________________________________
Mingw-w64-public mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/mingw-w64-public

Reply via email to