2017-07-27 15:08:47 +00:00
|
|
|
|
Index: gcc/common.opt
|
|
|
|
|
===================================================================
|
2017-09-25 20:42:27 +00:00
|
|
|
|
--- gcc/common.opt.orig 2017-09-25 22:33:46.000000000 +0200
|
|
|
|
|
+++ gcc/common.opt 2017-09-25 22:33:48.000000000 +0200
|
2017-07-27 15:08:47 +00:00
|
|
|
|
@@ -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
|
|
|
|
|
===================================================================
|
2017-09-25 20:42:27 +00:00
|
|
|
|
--- gcc/explow.c.orig 2017-09-25 22:33:46.000000000 +0200
|
|
|
|
|
+++ gcc/explow.c 2017-09-25 22:39:33.000000000 +0200
|
2017-07-27 15:08:47 +00:00
|
|
|
|
@@ -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;
|
2017-09-25 20:42:27 +00:00
|
|
|
|
+ rtx loop_lab, end_lab, skip_lab, last_size, before_skip;
|
2017-07-27 15:08:47 +00:00
|
|
|
|
+ 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
|
2017-09-25 20:42:27 +00:00
|
|
|
|
@@ -1398,6 +1402,30 @@ allocate_dynamic_stack_space (rtx size,
|
2017-07-27 15:08:47 +00:00
|
|
|
|
/* 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 ();
|
2017-09-25 20:42:27 +00:00
|
|
|
|
+ skip_lab = gen_label_rtx ();
|
|
|
|
|
+ /* We insert 'target = virtual_stack_dynamic_rtx' here, but target
|
|
|
|
|
+ is changed later, so that insn can be constructed only later. */
|
|
|
|
|
+ before_skip = get_last_insn ();
|
|
|
|
|
+ emit_cmp_and_jump_insns (size, CONST0_RTX (Pmode), EQ, NULL_RTX,
|
|
|
|
|
+ Pmode, 1, skip_lab);
|
2017-07-27 15:08:47 +00:00
|
|
|
|
+ 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(). */
|
2017-09-25 20:42:27 +00:00
|
|
|
|
@@ -1463,6 +1491,15 @@ allocate_dynamic_stack_space (rtx size,
|
2017-07-27 15:08:47 +00:00
|
|
|
|
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;
|
|
|
|
|
|
2017-09-25 20:42:27 +00:00
|
|
|
|
@@ -1474,6 +1511,17 @@ allocate_dynamic_stack_space (rtx size,
|
2017-07-27 15:08:47 +00:00
|
|
|
|
emit_label (final_label);
|
|
|
|
|
target = final_target;
|
|
|
|
|
}
|
|
|
|
|
+ if (flag_stack_clash_protection)
|
2017-09-25 20:42:27 +00:00
|
|
|
|
+ {
|
|
|
|
|
+ rtx seq;
|
|
|
|
|
+ emit_stack_probe (target);
|
|
|
|
|
+ emit_label (skip_lab);
|
|
|
|
|
+ start_sequence ();
|
|
|
|
|
+ emit_move_insn (target, virtual_stack_dynamic_rtx);
|
|
|
|
|
+ seq = get_insns ();
|
|
|
|
|
+ end_sequence ();
|
|
|
|
|
+ emit_insn_after (seq, before_skip);
|
|
|
|
|
+ }
|
2017-07-27 15:08:47 +00:00
|
|
|
|
|
|
|
|
|
if (must_align)
|
|
|
|
|
{
|
2017-09-25 20:42:27 +00:00
|
|
|
|
@@ -1544,8 +1592,6 @@ emit_stack_probe (rtx address)
|
2017-07-27 15:08:47 +00:00
|
|
|
|
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
|