Merge bitcoin/bitcoin#24843: [23.x] rc5 backports

a75b8ec836 guix: fix GCC 10.3.0 + mingw-w64 setjmp/longjmp issues (fanquake)

Pull request description:

  Currently backports:
  * https://github.com/bitcoin/bitcoin/pull/24842

ACKs for top commit:
  gruve-p:
    ACK a75b8ec836
  hebasto:
    ACK a75b8ec836
  jonatack:
    Code review and commit meta-data ACK a75b8ec836
  jarolrod:
    ACK a75b8ec836

Tree-SHA512: 1071b675647ed990ffda9c84391538b6c2e741b423a64e534754322250ca7f95cbc948e005cb976bf070099038f86997bfa1946c543a109e2086d2aaeaacb189
This commit is contained in:
laanwj 2022-04-14 17:23:02 +02:00
commit dabac355c8
No known key found for this signature in database
GPG key ID: 1E4AED62986CD25D
2 changed files with 72 additions and 3 deletions

View file

@ -166,9 +166,10 @@ desirable for building Bitcoin Core release binaries."
(define (make-gcc-without-newlib gcc)
(package-with-extra-configure-variable gcc "--with-newlib" "no"))
(define (make-mingw-w64-cross-gcc-vmov-alignment cross-gcc)
(define (make-mingw-w64-cross-gcc cross-gcc)
(package-with-extra-patches cross-gcc
(search-our-patches "vmov-alignment.patch")))
(search-our-patches "vmov-alignment.patch"
"gcc-broken-longjmp.patch")))
(define (make-mingw-pthreads-cross-toolchain target)
"Create a cross-compilation toolchain package for TARGET"
@ -176,7 +177,7 @@ desirable for building Bitcoin Core release binaries."
(pthreads-xlibc mingw-w64-x86_64-winpthreads)
(pthreads-xgcc (make-gcc-with-pthreads
(cross-gcc target
#:xgcc (make-gcc-without-newlib (make-ssp-fixed-gcc (make-mingw-w64-cross-gcc-vmov-alignment base-gcc)))
#:xgcc (make-gcc-without-newlib (make-ssp-fixed-gcc (make-mingw-w64-cross-gcc base-gcc)))
#:xbinutils xbinutils
#:libc pthreads-xlibc))))
;; Define a meta-package that propagates the resulting XBINUTILS, XLIBC, and

View file

@ -0,0 +1,68 @@
commit eb5698897c52702498938592d7f76e67d126451f
Author: Eric Botcazou <ebotcazou@adacore.com>
Date: Wed May 5 22:48:51 2021 +0200
Fix PR target/100402
This is a regression for 64-bit Windows present from mainline down to the 9
branch and introduced by the fix for PR target/99234. Again SEH, but with
a twist related to the way MinGW implements setjmp/longjmp, which turns out
to be piggybacked on SEH with recent versions of MinGW, i.e. the longjmp
performs a bona-fide unwinding of the stack, because it calls RtlUnwindEx
with the second argument initially passed to setjmp, which is the result of
__builtin_frame_address (0) in the MinGW header file:
define setjmp(BUF) _setjmp((BUF), __builtin_frame_address (0))
This means that we directly expose the frame pointer to the SEH machinery
here (unlike with regular exception handling where we use an intermediate
CFA) and thus that we cannot do whatever we want with it. The old code
would leave it unaligned, i.e. not multiple of 16, whereas the new code
aligns it, but this breaks for some reason; at least it appears that a
.seh_setframe directive with 0 as second argument always works, so the
fix aligns it this way.
gcc/
PR target/100402
* config/i386/i386.c (ix86_compute_frame_layout): For a SEH target,
always return the establisher frame for __builtin_frame_address (0).
gcc/testsuite/
* gcc.c-torture/execute/20210505-1.c: New test.
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index 2f838840e96..06ad1b2274e 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -6356,12 +6356,29 @@ ix86_compute_frame_layout (void)
area, see the SEH code in config/i386/winnt.c for the rationale. */
frame->hard_frame_pointer_offset = frame->sse_reg_save_offset;
- /* If we can leave the frame pointer where it is, do so. Also, return
+ /* If we can leave the frame pointer where it is, do so; however return
the establisher frame for __builtin_frame_address (0) or else if the
- frame overflows the SEH maximum frame size. */
+ frame overflows the SEH maximum frame size.
+
+ Note that the value returned by __builtin_frame_address (0) is quite
+ constrained, because setjmp is piggybacked on the SEH machinery with
+ recent versions of MinGW:
+
+ # elif defined(__SEH__)
+ # if defined(__aarch64__) || defined(_ARM64_)
+ # define setjmp(BUF) _setjmp((BUF), __builtin_sponentry())
+ # elif (__MINGW_GCC_VERSION < 40702)
+ # define setjmp(BUF) _setjmp((BUF), mingw_getsp())
+ # else
+ # define setjmp(BUF) _setjmp((BUF), __builtin_frame_address (0))
+ # endif
+
+ and the second argument passed to _setjmp, if not null, is forwarded
+ to the TargetFrame parameter of RtlUnwindEx by longjmp (after it has
+ built an ExceptionRecord on the fly describing the setjmp buffer). */
const HOST_WIDE_INT diff
= frame->stack_pointer_offset - frame->hard_frame_pointer_offset;
- if (diff <= 255)
+ if (diff <= 255 && !crtl->accesses_prior_frames)
{
/* The resulting diff will be a multiple of 16 lower than 255,
i.e. at most 240 as required by the unwind data structure. */