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