public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH] Fix PR64242
@ 2018-11-29 19:26 Wilco Dijkstra
  2018-11-30 23:07 ` Jeff Law
  0 siblings, 1 reply; 8+ messages in thread
From: Wilco Dijkstra @ 2018-11-29 19:26 UTC (permalink / raw)
  To: GCC Patches; +Cc: nd

Fix PR64242 - the middle end expansion for long jmp updates the
hard frame pointer before it reads the new stack pointer.  This
results in a corrupted stack pointer if the jmp buffer is a local.
The obvious fix is to insert a temporary.

AArch64 bootstrap & regress pass. OK to commit?

ChangeLog:
2018-11-29  Wilco Dijkstra  <wdijkstr@arm.com>

gcc/
	PR middle-end/64242
	* builtins.c (expand_builtin_longjmp): Use a temporary when restoring
	the frame pointer.
	(expand_builtin_nonlocal_goto): Likewise.

testsuite/
	PR middle-end/64242
	* gcc.c-torture/execute/pr64242.c: New test.

---
diff --git a/gcc/builtins.c b/gcc/builtins.c
index ebde2db6e6494cf7e4441f6834e65fcb81e1629c..5c80c60378fc4fbb3faf8e04672d7091ac071624 100644
--- a/gcc/builtins.c
+++ b/gcc/builtins.c
@@ -1142,8 +1142,11 @@ expand_builtin_longjmp (rtx buf_addr, rtx value)
 	  emit_clobber (gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (VOIDmode)));
 	  emit_clobber (gen_rtx_MEM (BLKmode, hard_frame_pointer_rtx));
 
-	  emit_move_insn (hard_frame_pointer_rtx, fp);
+	  /* Restore the frame pointer and stack pointer.  We must use a
+	     temporary since the setjmp buffer may be a local.  */
+	  fp = copy_to_reg (fp);
 	  emit_stack_restore (SAVE_NONLOCAL, stack);
+	  emit_move_insn (hard_frame_pointer_rtx, fp);
 
 	  emit_use (hard_frame_pointer_rtx);
 	  emit_use (stack_pointer_rtx);
@@ -1286,9 +1289,11 @@ expand_builtin_nonlocal_goto (tree exp)
       emit_clobber (gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (VOIDmode)));
       emit_clobber (gen_rtx_MEM (BLKmode, hard_frame_pointer_rtx));
 
-      /* Restore frame pointer for containing function.  */
-      emit_move_insn (hard_frame_pointer_rtx, r_fp);
+      /* Restore the frame pointer and stack pointer.  We must use a
+	 temporary since the setjmp buffer may be a local.  */
+      r_fp = copy_to_reg (r_fp);
       emit_stack_restore (SAVE_NONLOCAL, r_sp);
+      emit_move_insn (hard_frame_pointer_rtx, r_fp);
 
       /* USE of hard_frame_pointer_rtx added for consistency;
 	 not clear if really needed.  */
diff --git a/gcc/testsuite/gcc.c-torture/execute/pr64242.c b/gcc/testsuite/gcc.c-torture/execute/pr64242.c
new file mode 100644
index 0000000000000000000000000000000000000000..72dab5709203437b50514a70c523d104706e4bda
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/execute/pr64242.c
@@ -0,0 +1,30 @@
+/* { dg-require-effective-target indirect_jumps } */
+
+extern void abort (void);
+
+__attribute ((noinline)) void
+broken_longjmp(void *p)
+{
+  void *buf[5];
+  __builtin_memcpy (buf, p, 5 * sizeof (void*));
+  /* Corrupts stack pointer...  */
+  __builtin_longjmp (buf, 1);
+}
+
+volatile int x = 0;
+volatile void *p;
+int
+main (void)
+{
+  void *buf[5];
+  p = __builtin_alloca (x);
+
+  if (!__builtin_setjmp (buf))
+    broken_longjmp (buf);
+
+  /* Fails if stack pointer corrupted.  */
+  if (p != __builtin_alloca (x))
+    abort();
+
+  return 0;
+}

^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2018-12-04 10:23 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-11-29 19:26 [PATCH] Fix PR64242 Wilco Dijkstra
2018-11-30 23:07 ` Jeff Law
2018-12-03 13:34   ` Richard Biener
2018-12-03 13:40     ` Christophe Lyon
2018-12-03 16:26   ` Jakub Jelinek
2018-12-03 18:53     ` Jeff Law
2018-12-04 10:20     ` Christophe Lyon
2018-12-04 10:23       ` Jakub Jelinek

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