On Sun, 31 Aug 2025, Pali Rohár wrote:

When the msvc setjmpex.h file is included in source file then msvc changes
the behavior of C setjmp() and longjmp() calls to be SEH safe. Without
including the setjmpex.h file, these C calls are not SEH safe by default.

In following table is behavior of the msvc compiler, which symbols are
called in the emitted binary object code (not linked):

              without setjmpex.h         with setjmpex.h

   i386      _setjmp3  + longjmp      _setjmp3  + _longjmpex
   amd64     _setjmp   + longjmp      _setjmpex + longjmp
   arm32     _setjmp   + longjmp      _setjmpex + longjmp
   arm64     _setjmpex + longjmp      _setjmpex + longjmp

This table was produced from results on https://godbolt.org/z/Gabv1qT9c

When the compiled code is linked into final binary with UCRT library, the
_setjmp symbol is resolved to UCRT _intrinsic_setjmp symbol and the
_setjmpex symbol is resolved to UCRT _intrinsic_setjmpex. i386 _setjmp3
stays as without the _intrinsic prefix and the i386 _setjmp is not emitted
at all.

Fix the mingw-w64 setjmpex.h and setjmp.h include files to define setjmp()
and longjmp() macros which expands to functions emitted by msvc compiler to
match the msvc behavior.

Note that msvc setjmpex.h and setjmp.h header files are different than
mingw-w64 and is because it looks like that msvc compiler parses the source
code with setjmp and longjmp keywords differently and is doing some
transformations not specified in header files. Something which gcc is not
doing.

mingw-w64 setjmpex.h and setjmp.h files are defined based on the
observation of output from msvc compiler, not from the msvc header files.
---
mingw-w64-headers/crt/setjmp.h   | 104 ++++++++++++++++++-------------
mingw-w64-headers/crt/setjmpex.h |  16 +----
2 files changed, 63 insertions(+), 57 deletions(-)

diff --git a/mingw-w64-headers/crt/setjmp.h b/mingw-w64-headers/crt/setjmp.h
index 54e3ad03b67f..0d85d0e9f9f8 100644
--- a/mingw-w64-headers/crt/setjmp.h
+++ b/mingw-w64-headers/crt/setjmp.h
@@ -26,7 +26,7 @@
extern "C" {
#endif

-#if (defined(_X86_) && !defined(__x86_64))
+#if defined(__i386__)

#define _JBLEN 16
#define _JBTYPE int
@@ -40,6 +40,7 @@ extern "C" {
    unsigned long Eip;
    unsigned long Registration;
    unsigned long TryLevel;
+    /* Following fields are only for new _setjmp3(), the are not for old 
_setjmp(). */
    unsigned long Cookie;
    unsigned long UnwindFunc;
    unsigned long UnwindData[6];
@@ -107,7 +108,7 @@ extern "C" {

  } _JUMP_BUFFER;

-#elif defined(__x86_64)
+#elif defined(__x86_64__)


These changes to ifdefs (this one and the i386 one above) are ok, but ideally I wouldn't have them intermixed with other functional changes like this one. But it's not fatally distracting in the case of this commit anyway, so it's ok this time.

Same with the added comment - I don't really see if it is logically connected to the rest of this change, or if it just happened to end up in this same commit.

// Martin

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

Reply via email to