File gcc48-stack-probe.diff of Package cross-s390x-gcc48-icecream-backend

Index: gcc/common.opt
===================================================================
--- gcc/common.opt.orig	2017-07-27 16:54:16.000000000 +0200
+++ gcc/common.opt	2017-07-27 16:54:20.000000000 +0200
@@ -1894,6 +1894,10 @@ fstack-check
 Common Alias(fstack-check=, specific, no)
 Insert stack checking code into the program.  Same as -fstack-check=specific
 
+fstack-clash-protection
+Common Report Var(flag_stack_clash_protection)
+Insert probes per page for dynamically allocated stack space
+
 fstack-limit
 Common Var(common_deferred_options) Defer
 
Index: gcc/explow.c
===================================================================
--- gcc/explow.c.orig	2017-07-27 16:54:16.000000000 +0200
+++ gcc/explow.c	2017-07-27 16:59:32.000000000 +0200
@@ -1140,6 +1140,8 @@ update_nonlocal_goto_save_area (void)
   emit_stack_save (SAVE_NONLOCAL, &r_save);
 }
 
+#define PROBE_INTERVAL (1 << STACK_CHECK_PROBE_INTERVAL_EXP)
+
 /* Return an rtx representing the address of an area of memory dynamically
    pushed on the stack.
 
@@ -1169,6 +1171,8 @@ allocate_dynamic_stack_space (rtx size,
   rtx final_label, final_target, target;
   unsigned extra_align = 0;
   bool must_align;
+  rtx loop_lab, end_lab, last_size;
+  int probe_pass = 0;
 
   /* If we're asking for zero bytes, it doesn't matter what we point
      to since we can't dereference it.  But return a reasonable
@@ -1398,6 +1402,24 @@ allocate_dynamic_stack_space (rtx size,
   /* Don't let anti_adjust_stack emit notes.  */
   suppress_reg_args_size = true;
 
+  if (flag_stack_clash_protection)
+    {
+      size = copy_to_mode_reg (Pmode, convert_to_mode (Pmode, size, 1));
+      loop_lab = gen_label_rtx ();
+      end_lab = gen_label_rtx ();
+      emit_label (loop_lab);
+#ifndef STACK_GROWS_DOWNWARD
+#error stack must grow down
+#endif
+      emit_cmp_and_jump_insns (size, GEN_INT (PROBE_INTERVAL), LTU,
+			       NULL_RTX, Pmode, 1, end_lab);
+      last_size = expand_binop (Pmode, sub_optab, size, GEN_INT (PROBE_INTERVAL), size,
+				1, OPTAB_WIDEN);
+      gcc_assert (last_size == size);
+      size = GEN_INT (PROBE_INTERVAL);
+    }
+
+again:
   /* Perform the required allocation from the stack.  Some systems do
      this differently than simply incrementing/decrementing from the
      stack pointer, such as acquiring the space by calling malloc().  */
@@ -1463,6 +1485,15 @@ allocate_dynamic_stack_space (rtx size,
       emit_move_insn (target, virtual_stack_dynamic_rtx);
 #endif
     }
+  if ((flag_stack_clash_protection) && probe_pass == 0)
+    {
+      probe_pass = 1;
+      emit_stack_probe (target);
+      emit_jump (loop_lab);
+      emit_label (end_lab);
+      size = last_size;
+      goto again;
+    }
 
   suppress_reg_args_size = false;
 
@@ -1474,6 +1505,8 @@ allocate_dynamic_stack_space (rtx size,
       emit_label (final_label);
       target = final_target;
     }
+  if (flag_stack_clash_protection)
+    emit_stack_probe (target);
 
   if (must_align)
     {
@@ -1544,8 +1577,6 @@ emit_stack_probe (rtx address)
    the current stack pointer.  STACK_GROWS_DOWNWARD says whether to add
    or subtract them from the stack pointer.  */
 
-#define PROBE_INTERVAL (1 << STACK_CHECK_PROBE_INTERVAL_EXP)
-
 #ifdef STACK_GROWS_DOWNWARD
 #define STACK_GROW_OP MINUS
 #define STACK_GROW_OPTAB sub_optab
openSUSE Build Service is sponsored by