Files
gcc48/gcc48-stack-probe.diff
2017-09-25 20:42:27 +00:00

112 lines
3.8 KiB
Diff
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

Index: gcc/common.opt
===================================================================
--- gcc/common.opt.orig 2017-09-25 22:33:46.000000000 +0200
+++ gcc/common.opt 2017-09-25 22:33:48.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-09-25 22:33:46.000000000 +0200
+++ gcc/explow.c 2017-09-25 22:39:33.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, skip_lab, last_size, before_skip;
+ 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,30 @@ 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 ();
+ 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);
+ 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 +1491,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 +1511,17 @@ allocate_dynamic_stack_space (rtx size,
emit_label (final_label);
target = final_target;
}
+ if (flag_stack_clash_protection)
+ {
+ 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);
+ }
if (must_align)
{
@@ -1544,8 +1592,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