Merge pull request #8052 from lazka/gcc-backports
gcc: backport some upstream fixes
This commit is contained in:
110
mingw-w64-gcc/0200-backport-7fc0f78.patch
Normal file
110
mingw-w64-gcc/0200-backport-7fc0f78.patch
Normal file
@@ -0,0 +1,110 @@
|
||||
From 5883d709d2c63a534b959583cb9ef15a2785de9a Mon Sep 17 00:00:00 2001
|
||||
From: Liu Hao <lh_mouse@126.com>
|
||||
Date: Thu, 8 Oct 2020 10:26:13 +0800
|
||||
Subject: [PATCH] libsupc++: Make the destructor parameter to
|
||||
`__cxa_thread_atexit()` use the `__thiscall` calling convention for
|
||||
i686-w64-mingw32
|
||||
|
||||
The mingw-w64 implementations of `__cxa_thread_atexit()` and `__cxa_atexit()` have been
|
||||
using `__thiscall` since two years ago. Using the default calling convention (which is
|
||||
`__cdecl`) causes crashes as explained in PR83562.
|
||||
|
||||
Calling conventions have no effect on x86_64-w64-mingw32.
|
||||
|
||||
Reference: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83562
|
||||
Reference: https://sourceforge.net/p/mingw-w64/mingw-w64/ci/master/tree/mingw-w64-crt/crt/cxa_thread_atexit.c
|
||||
Reference: https://sourceforge.net/p/mingw-w64/mingw-w64/ci/f3e0fbb40cbc9f8821db8bd8a0c4dae8ff671e9f/
|
||||
Reference: https://github.com/msys2/MINGW-packages/issues/7071
|
||||
Signed-off-by: Liu Hao <lh_mouse@126.com>
|
||||
|
||||
2020-10-08 Liu Hao <lh_mouse@126.com>
|
||||
|
||||
libstdc++-v3:
|
||||
* libsupc++/cxxabi.h: (__cxa_atexit): mark with _GLIBCXX_CDTOR_CALLABI
|
||||
(__cxa_thread_atexit): ditto
|
||||
* libsupc++/atexit_thread.cc: (__cxa_atexit): mark with
|
||||
_GLIBCXX_CDTOR_CALLABI
|
||||
(__cxa_thread_atexit): ditto
|
||||
(elt): ditto
|
||||
---
|
||||
libstdc++-v3/libsupc++/atexit_thread.cc | 14 ++++++++++----
|
||||
libstdc++-v3/libsupc++/cxxabi.h | 8 ++++++++
|
||||
2 files changed, 18 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/libstdc++-v3/libsupc++/atexit_thread.cc b/libstdc++-v3/libsupc++/atexit_thread.cc
|
||||
index e97644f8cd4..4f7f982ac6b 100644
|
||||
--- a/libstdc++-v3/libsupc++/atexit_thread.cc
|
||||
+++ b/libstdc++-v3/libsupc++/atexit_thread.cc
|
||||
@@ -30,16 +30,21 @@
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
+// Simplify it a little for this file.
|
||||
+#ifndef _GLIBCXX_CDTOR_CALLABI
|
||||
+# define _GLIBCXX_CDTOR_CALLABI
|
||||
+#endif
|
||||
+
|
||||
#if _GLIBCXX_HAVE___CXA_THREAD_ATEXIT
|
||||
|
||||
// Libc provides __cxa_thread_atexit definition.
|
||||
|
||||
#elif _GLIBCXX_HAVE___CXA_THREAD_ATEXIT_IMPL
|
||||
|
||||
-extern "C" int __cxa_thread_atexit_impl (void (*func) (void *),
|
||||
+extern "C" int __cxa_thread_atexit_impl (void (_GLIBCXX_CDTOR_CALLABI *func) (void *),
|
||||
void *arg, void *d);
|
||||
extern "C" int
|
||||
-__cxxabiv1::__cxa_thread_atexit (void (*dtor)(void *),
|
||||
+__cxxabiv1::__cxa_thread_atexit (void (_GLIBCXX_CDTOR_CALLABI *dtor)(void *),
|
||||
void *obj, void *dso_handle)
|
||||
_GLIBCXX_NOTHROW
|
||||
{
|
||||
@@ -52,7 +57,7 @@ namespace {
|
||||
// One element in a singly-linked stack of cleanups.
|
||||
struct elt
|
||||
{
|
||||
- void (*destructor)(void *);
|
||||
+ void (_GLIBCXX_CDTOR_CALLABI *destructor)(void *);
|
||||
void *object;
|
||||
elt *next;
|
||||
#ifdef _GLIBCXX_THREAD_ATEXIT_WIN32
|
||||
@@ -116,7 +121,8 @@ namespace {
|
||||
}
|
||||
|
||||
extern "C" int
|
||||
-__cxxabiv1::__cxa_thread_atexit (void (*dtor)(void *), void *obj, void */*dso_handle*/)
|
||||
+__cxxabiv1::__cxa_thread_atexit (void (_GLIBCXX_CDTOR_CALLABI *dtor)(void *),
|
||||
+ void *obj, void */*dso_handle*/)
|
||||
_GLIBCXX_NOTHROW
|
||||
{
|
||||
// Do this initialization once.
|
||||
diff --git a/libstdc++-v3/libsupc++/cxxabi.h b/libstdc++-v3/libsupc++/cxxabi.h
|
||||
index 50298205daa..e6244c7f5ac 100644
|
||||
--- a/libstdc++-v3/libsupc++/cxxabi.h
|
||||
+++ b/libstdc++-v3/libsupc++/cxxabi.h
|
||||
@@ -125,14 +125,22 @@ namespace __cxxabiv1
|
||||
|
||||
// DSO destruction.
|
||||
int
|
||||
+#ifdef _GLIBCXX_CDTOR_CALLABI
|
||||
+ __cxa_atexit(void (_GLIBCXX_CDTOR_CALLABI *)(void*), void*, void*) _GLIBCXX_NOTHROW;
|
||||
+#else
|
||||
__cxa_atexit(void (*)(void*), void*, void*) _GLIBCXX_NOTHROW;
|
||||
+#endif
|
||||
|
||||
int
|
||||
__cxa_finalize(void*);
|
||||
|
||||
// TLS destruction.
|
||||
int
|
||||
+#ifdef _GLIBCXX_CDTOR_CALLABI
|
||||
+ __cxa_thread_atexit(void (_GLIBCXX_CDTOR_CALLABI *)(void*), void*, void *) _GLIBCXX_NOTHROW;
|
||||
+#else
|
||||
__cxa_thread_atexit(void (*)(void*), void*, void *) _GLIBCXX_NOTHROW;
|
||||
+#endif
|
||||
|
||||
// Pure virtual functions.
|
||||
void
|
||||
--
|
||||
2.30.1
|
||||
|
||||
225
mingw-w64-gcc/0201-backport-49a714e.patch
Normal file
225
mingw-w64-gcc/0201-backport-49a714e.patch
Normal file
@@ -0,0 +1,225 @@
|
||||
From 49a714e59194a7c549aa6657676a1b4be4520650 Mon Sep 17 00:00:00 2001
|
||||
From: Eric Botcazou <ebotcazou@adacore.com>
|
||||
Date: Mon, 1 Mar 2021 07:53:05 +0100
|
||||
Subject: [PATCH] Fix wrong result for 1.0/3.0 at -O2 -fno-omit-frame-pointer
|
||||
-frounding-math
|
||||
|
||||
This wrong-code PR for the C++ compiler on x86-64/Windows is a regression
|
||||
in GCC 9 and later, but the underlying issue has probably been there since
|
||||
SEH was implemented and is exposed by this comment in config/i386/winnt.c:
|
||||
|
||||
/* SEH records saves relative to the "current" stack pointer, whether
|
||||
or not there's a frame pointer in place. This tracks the current
|
||||
stack pointer offset from the CFA. */
|
||||
HOST_WIDE_INT sp_offset;
|
||||
|
||||
That's not what the (current) Microsoft documentation says; instead it says:
|
||||
|
||||
/* SEH records offsets relative to the lowest address of the fixed stack
|
||||
allocation. If there is no frame pointer, these offsets are from the
|
||||
stack pointer; if there is a frame pointer, these offsets are from the
|
||||
value of the stack pointer when the frame pointer was established, i.e.
|
||||
the frame pointer minus the offset in the .seh_setframe directive. */
|
||||
|
||||
That's why the implementation is correct only under the condition that the
|
||||
frame pointer be established *after* the fixed stack allocation; as a matter
|
||||
of fact, that's clearly the model underpinning SEH, but is the opposite of
|
||||
what is done e.g. on Linux.
|
||||
|
||||
However the issue is mostly papered over in practice because:
|
||||
|
||||
1. SEH forces use_fast_prologue_epilogue to false, which in turns forces
|
||||
save_regs_using_mov to false, so the general regs are always pushed when
|
||||
they need to be saved, which eliminates the offset computation for them.
|
||||
|
||||
2. As soon as a frame is larger than 240 bytes, the frame pointer is fixed
|
||||
arbitrarily to 128 bytes above the stack pointer, which of course requires
|
||||
that it be established after the fixed stack allocation.
|
||||
|
||||
So you need a small frame clobbering one of the call-saved XMM registers in
|
||||
order to generate wrong SEH unwind info.
|
||||
|
||||
The attached fix makes sure that the frame pointer is always established
|
||||
after the fixed stack allocation by pointing it at or below the lowest used
|
||||
register save area, i.e. the SSE save area, and removing the special early
|
||||
saves in the prologue; the end result is a uniform prologue sequence for
|
||||
SEH whatever the frame size. And it avoids a discrepancy between cases
|
||||
where the number of saved general regs is even and cases where it is odd.
|
||||
|
||||
gcc/
|
||||
PR target/99234
|
||||
* config/i386/i386.c (ix86_compute_frame_layout): For a SEH target,
|
||||
point the hard frame pointer to the SSE register save area instead
|
||||
of the general register save area. Perform only minimal adjustment
|
||||
for small frames if it is initially not correctly aligned.
|
||||
(ix86_expand_prologue): Remove early saves for a SEH target.
|
||||
* config/i386/winnt.c (struct seh_frame_state): Document constraint.
|
||||
gcc/testsuite/
|
||||
* g++.dg/eh/seh-xmm-unwind.C: New test.
|
||||
---
|
||||
gcc/config/i386/i386.c | 35 +++++---------
|
||||
gcc/config/i386/winnt.c | 17 +++++--
|
||||
gcc/testsuite/g++.dg/eh/seh-xmm-unwind.C | 61 ++++++++++++++++++++++++
|
||||
3 files changed, 88 insertions(+), 25 deletions(-)
|
||||
create mode 100644 gcc/testsuite/g++.dg/eh/seh-xmm-unwind.C
|
||||
|
||||
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
|
||||
index aedf7873ce5..7b803661366 100644
|
||||
--- a/gcc/config/i386/i386.c
|
||||
+++ b/gcc/config/i386/i386.c
|
||||
@@ -6190,11 +6190,6 @@ ix86_compute_frame_layout (void)
|
||||
offset += frame->nregs * UNITS_PER_WORD;
|
||||
frame->reg_save_offset = offset;
|
||||
|
||||
- /* On SEH target, registers are pushed just before the frame pointer
|
||||
- location. */
|
||||
- if (TARGET_SEH)
|
||||
- frame->hard_frame_pointer_offset = offset;
|
||||
-
|
||||
/* Calculate the size of the va-arg area (not including padding, if any). */
|
||||
frame->va_arg_size = ix86_varargs_gpr_size + ix86_varargs_fpr_size;
|
||||
|
||||
@@ -6357,14 +6352,21 @@ ix86_compute_frame_layout (void)
|
||||
the unwind data structure. */
|
||||
if (TARGET_SEH)
|
||||
{
|
||||
- HOST_WIDE_INT diff;
|
||||
+ /* Force the frame pointer to point at or below the lowest register save
|
||||
+ 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, returns
|
||||
+ /* If we can leave the frame pointer where it is, do so. Also, return
|
||||
the establisher frame for __builtin_frame_address (0). */
|
||||
- diff = frame->stack_pointer_offset - frame->hard_frame_pointer_offset;
|
||||
- if (diff <= SEH_MAX_FRAME_SIZE
|
||||
- && (diff > 240 || (diff & 15) != 0)
|
||||
- && !crtl->accesses_prior_frames)
|
||||
+ const HOST_WIDE_INT diff
|
||||
+ = frame->stack_pointer_offset - frame->hard_frame_pointer_offset;
|
||||
+ if (diff <= 255)
|
||||
+ {
|
||||
+ /* The resulting diff will be a multiple of 16 lower than 255,
|
||||
+ i.e. at most 240 as required by the unwind data structure. */
|
||||
+ frame->hard_frame_pointer_offset += (diff & 15);
|
||||
+ }
|
||||
+ else if (diff <= SEH_MAX_FRAME_SIZE && !crtl->accesses_prior_frames)
|
||||
{
|
||||
/* Ideally we'd determine what portion of the local stack frame
|
||||
(within the constraint of the lowest 240) is most heavily used.
|
||||
@@ -8170,17 +8172,6 @@ ix86_expand_prologue (void)
|
||||
insn = emit_insn (gen_push (hard_frame_pointer_rtx));
|
||||
RTX_FRAME_RELATED_P (insn) = 1;
|
||||
|
||||
- /* Push registers now, before setting the frame pointer
|
||||
- on SEH target. */
|
||||
- if (!int_registers_saved
|
||||
- && TARGET_SEH
|
||||
- && !frame.save_regs_using_mov)
|
||||
- {
|
||||
- ix86_emit_save_regs ();
|
||||
- int_registers_saved = true;
|
||||
- gcc_assert (m->fs.sp_offset == frame.reg_save_offset);
|
||||
- }
|
||||
-
|
||||
if (m->fs.sp_offset == frame.hard_frame_pointer_offset)
|
||||
{
|
||||
insn = emit_move_insn (hard_frame_pointer_rtx, stack_pointer_rtx);
|
||||
diff --git a/gcc/config/i386/winnt.c b/gcc/config/i386/winnt.c
|
||||
index eae3ee2ef9a..201f69e74c4 100644
|
||||
--- a/gcc/config/i386/winnt.c
|
||||
+++ b/gcc/config/i386/winnt.c
|
||||
@@ -830,9 +830,20 @@ i386_pe_asm_lto_end (void)
|
||||
|
||||
struct seh_frame_state
|
||||
{
|
||||
- /* SEH records saves relative to the "current" stack pointer, whether
|
||||
- or not there's a frame pointer in place. This tracks the current
|
||||
- stack pointer offset from the CFA. */
|
||||
+ /* SEH records offsets relative to the lowest address of the fixed stack
|
||||
+ allocation. If there is no frame pointer, these offsets are from the
|
||||
+ stack pointer; if there is a frame pointer, these offsets are from the
|
||||
+ value of the stack pointer when the frame pointer was established, i.e.
|
||||
+ the frame pointer minus the offset in the .seh_setframe directive.
|
||||
+
|
||||
+ We do not distinguish these two cases, i.e. we consider that the offsets
|
||||
+ are always relative to the "current" stack pointer. This means that we
|
||||
+ need to perform the fixed stack allocation before establishing the frame
|
||||
+ pointer whenever there are registers to be saved, and this is guaranteed
|
||||
+ by the prologue provided that we force the frame pointer to point at or
|
||||
+ below the lowest used register save area, see ix86_compute_frame_layout.
|
||||
+
|
||||
+ This tracks the current stack pointer offset from the CFA. */
|
||||
HOST_WIDE_INT sp_offset;
|
||||
|
||||
/* The CFA is located at CFA_REG + CFA_OFFSET. */
|
||||
diff --git a/gcc/testsuite/g++.dg/eh/seh-xmm-unwind.C b/gcc/testsuite/g++.dg/eh/seh-xmm-unwind.C
|
||||
new file mode 100644
|
||||
index 00000000000..07fd805b3fd
|
||||
--- /dev/null
|
||||
+++ b/gcc/testsuite/g++.dg/eh/seh-xmm-unwind.C
|
||||
@@ -0,0 +1,61 @@
|
||||
+/* PR target/99234 */
|
||||
+/* Test SEH unwinding of XMM register saves. */
|
||||
+
|
||||
+/* { dg-do run { target { x86_64-*-mingw32 && lp64 } } } */
|
||||
+
|
||||
+extern "C" void abort (void);
|
||||
+extern "C" void exit (int);
|
||||
+
|
||||
+void
|
||||
+foo (void)
|
||||
+{
|
||||
+ register __int128 xmm6 asm("xmm6") = 0;
|
||||
+ register __int128 xmm7 asm("xmm7") = 0;
|
||||
+ register __int128 xmm8 asm("xmm8") = 0;
|
||||
+ register __int128 xmm9 asm("xmm9") = 0;
|
||||
+ register __int128 xmm10 asm("xmm10") = 0;
|
||||
+ register __int128 xmm11 asm("xmm11") = 0;
|
||||
+ register __int128 xmm12 asm("xmm12") = 0;
|
||||
+ register __int128 xmm13 asm("xmm13") = 0;
|
||||
+ register __int128 xmm14 asm("xmm14") = 0;
|
||||
+ register __int128 xmm15 asm("xmm15") = 0;
|
||||
+
|
||||
+ __asm__ __volatile__ ("" : "+x" (xmm6), "+x" (xmm7), "+x" (xmm8), "+x" (xmm9),
|
||||
+ "+x" (xmm10), "+x" (xmm11), "+x" (xmm12), "+x" (xmm13),
|
||||
+ "+x" (xmm14), "+x" (xmm15));
|
||||
+
|
||||
+ throw 1;
|
||||
+}
|
||||
+
|
||||
+int
|
||||
+main (void)
|
||||
+{
|
||||
+ register __int128 xmm6 asm("xmm6") = 6;
|
||||
+ register __int128 xmm7 asm("xmm7") = 7;
|
||||
+ register __int128 xmm8 asm("xmm8") = 8;
|
||||
+ register __int128 xmm9 asm("xmm9") = 9;
|
||||
+ register __int128 xmm10 asm("xmm10") = 10;
|
||||
+ register __int128 xmm11 asm("xmm11") = 11;
|
||||
+ register __int128 xmm12 asm("xmm12") = 12;
|
||||
+ register __int128 xmm13 asm("xmm13") = 13;
|
||||
+ register __int128 xmm14 asm("xmm14") = 14;
|
||||
+ register __int128 xmm15 asm("xmm15") = 15;
|
||||
+
|
||||
+ __asm__ __volatile__ ("" : "+x" (xmm6), "+x" (xmm7), "+x" (xmm8), "+x" (xmm9),
|
||||
+ "+x" (xmm10), "+x" (xmm11), "+x" (xmm12), "+x" (xmm13),
|
||||
+ "+x" (xmm14), "+x" (xmm15));
|
||||
+
|
||||
+ try {
|
||||
+ foo ();
|
||||
+ } catch (...) {
|
||||
+ __asm__ __volatile__ ("" : "+x" (xmm6), "+x" (xmm7), "+x" (xmm8), "+x" (xmm9),
|
||||
+ "+x" (xmm10), "+x" (xmm11), "+x" (xmm12), "+x" (xmm13),
|
||||
+ "+x" (xmm14), "+x" (xmm15));
|
||||
+
|
||||
+ if (xmm6 != 6 || xmm7 != 7 || xmm8 != 8 || xmm9 != 9 || xmm10 != 10
|
||||
+ || xmm11 != 11 || xmm12 != 12 || xmm13 != 13 || xmm14 != 14 || xmm15 != 15)
|
||||
+ abort ();
|
||||
+ }
|
||||
+
|
||||
+ exit (0);
|
||||
+}
|
||||
--
|
||||
2.27.0
|
||||
|
||||
@@ -24,7 +24,7 @@ pkgver=10.2.0
|
||||
#_majorver=${pkgver:0:1}
|
||||
#_sourcedir=${_realname}-${_majorver}-${_snapshot}
|
||||
_sourcedir=${_realname}-${pkgver}
|
||||
pkgrel=6
|
||||
pkgrel=7
|
||||
pkgdesc="GCC for the MinGW-w64"
|
||||
arch=('any')
|
||||
url="https://gcc.gnu.org"
|
||||
@@ -70,7 +70,9 @@ source=("https://ftp.gnu.org/gnu/gcc/${_realname}-${pkgver%%+*}/${_realname}-${p
|
||||
0130-libstdc++-in-out.patch
|
||||
0140-gcc-8.2.0-diagnostic-color.patch
|
||||
0150-gcc-10.2.0-libgcc-ldflags.patch
|
||||
0160-libbacktrace-seh.patch)
|
||||
0160-libbacktrace-seh.patch
|
||||
0200-backport-7fc0f78.patch
|
||||
0201-backport-49a714e.patch)
|
||||
sha256sums=('b8dd4368bb9c7f0b98188317ee0254dd8cc99d1e3a18d0ff146c855fe16c1d8c'
|
||||
'SKIP'
|
||||
'bce81824fc89e5e62cca350de4c17a27e27a18a1a1ad5ca3492aec1fc5af3234'
|
||||
@@ -94,7 +96,9 @@ sha256sums=('b8dd4368bb9c7f0b98188317ee0254dd8cc99d1e3a18d0ff146c855fe16c1d8c'
|
||||
'055289699c4222ef0b8125abdc8c9ceeff0712876c86e6d552a056fbacc14284'
|
||||
'5240a9e731b45c17a164066c7eb193c1fbee9fd8d9a2a5afa2edbcde9510da47'
|
||||
'7f0b4e45d933e18c9d8bd2afcd83e4f52e97e2e25dd41bfa0cba755c70e591c7'
|
||||
'88c1d65e763e631ad49f9a077ed631f4acac9ef4732e2818ccddaefc883b1811')
|
||||
'88c1d65e763e631ad49f9a077ed631f4acac9ef4732e2818ccddaefc883b1811'
|
||||
'90b0f1aae2e2f9d75520569e8fbb31a9bac507136dd103a966f063d28e2094b8'
|
||||
'6bcaf2846ceeafa87912b30ed3e573d75b35bbeafebdaf675e2318b9b0058fbb')
|
||||
validpgpkeys=(F3691687D867B81B51CE07D9BBE43771487328A9 # bpiotrowski@archlinux.org
|
||||
86CFFCA918CF3AF47147588051E8B148A9999C34 # evangelos@foutrelis.com
|
||||
13975A70E63C361C73AE69EF6EEB81F8981C74C7 # richard.guenther@gmail.com
|
||||
@@ -160,6 +164,14 @@ prepare() {
|
||||
apply_patch_with_msg \
|
||||
0160-libbacktrace-seh.patch
|
||||
|
||||
# https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83562
|
||||
apply_patch_with_msg \
|
||||
0200-backport-7fc0f78.patch
|
||||
|
||||
# https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99234
|
||||
apply_patch_with_msg \
|
||||
0201-backport-49a714e.patch
|
||||
|
||||
# do not expect ${prefix}/mingw symlink - this should be superceded by
|
||||
# 0005-Windows-Don-t-ignore-native-system-header-dir.patch .. but isn't!
|
||||
sed -i 's/${prefix}\/mingw\//${prefix}\//g' configure
|
||||
|
||||
Reference in New Issue
Block a user