public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* Fix PR target/100402
@ 2021-05-05 21:02 Eric Botcazou
  0 siblings, 0 replies; only message in thread
From: Eric Botcazou @ 2021-05-05 21:02 UTC (permalink / raw)
  To: gcc-patches

[-- Attachment #1: Type: text/plain, Size: 1450 bytes --]

This is a regression for 64-bit Windows present from mainline down to the 9
branch and introduced by my fix for PR target/99234.  Again SEH, but with a
twist related to the way MinGW implements setjmp/longjmp that I discovered
while debugging it: setjmp/longjmp is piggybacked on SEH with recent versions
of MinGW, i.e. the longjmp performs a bona-fide unwinding of the stack, as it
calls RtlUnwindEx with the second argument 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.

Tested on x86-64/Windows, applied on the affected branches as obvious.


2021-05-05  Eric Botcazou  <ebotcazou@adacore.com>

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


2021-05-05  Eric Botcazou  <ebotcazou@adacore.com>

	* gcc.c-torture/execute/20210505-1.c: New test.

-- 
Eric Botcazou

[-- Attachment #2: pr100402.diff --]
[-- Type: text/x-patch, Size: 1766 bytes --]

diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index 06b0f5814ea..ecc15358efe 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -6672,12 +6672,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.  */

[-- Attachment #3: 20210505-1.c --]
[-- Type: text/x-csrc, Size: 414 bytes --]

/* PR target/100402 */
/* Testcase by Hannes Domani <ssbssa@yahoo.de> */

/* { dg-require-effective-target indirect_jumps } */

#include <setjmp.h>
#include <stdbool.h>

static jmp_buf buf;
static _Bool stop = false;

void call_func (void(*func)(void))
{
  func ();
}

void func (void)
{
  stop = true;
  longjmp (buf, 1);
}

int main (void)
{
  setjmp (buf);

  while (!stop)
    call_func (func);

  return 0;
}

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2021-05-05 21:02 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-05-05 21:02 Fix PR target/100402 Eric Botcazou

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).