summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gnu/gcc/gcc/cfgexpand.c41
-rw-r--r--gnu/gcc/gcc/common.opt4
2 files changed, 33 insertions, 12 deletions
diff --git a/gnu/gcc/gcc/cfgexpand.c b/gnu/gcc/gcc/cfgexpand.c
index ccb534f0e18..88bc17a206c 100644
--- a/gnu/gcc/gcc/cfgexpand.c
+++ b/gnu/gcc/gcc/cfgexpand.c
@@ -429,7 +429,21 @@ partition_stack_vars (void)
if (n == 1)
return;
- qsort (stack_vars_sorted, n, sizeof (size_t), stack_var_size_cmp);
+ if (flag_stack_shuffle)
+ {
+ /* Fisher-Yates shuffle */
+ for (si = n - 1; si > 0; si--)
+ {
+ size_t tmp;
+ sj = arc4random_uniform(si);
+
+ tmp = stack_vars_sorted[si];
+ stack_vars_sorted[si] = stack_vars_sorted[sj];
+ stack_vars_sorted[sj] = tmp;
+ }
+ }
+ else
+ qsort (stack_vars_sorted, n, sizeof (size_t), stack_var_size_cmp);
/* Special case: detect when all variables conflict, and thus we can't
do anything during the partitioning loop. It isn't uncommon (with
@@ -1110,19 +1124,22 @@ expand_used_vars (void)
/* Assign rtl to each variable based on these partitions. */
if (stack_vars_num > 0)
{
- /* Reorder decls to be protected by iterating over the variables
- array multiple times, and allocating out of each phase in turn. */
- /* ??? We could probably integrate this into the qsort we did
- earlier, such that we naturally see these variables first,
- and thus naturally allocate things in the right order. */
- if (has_protected_decls)
+ if (!flag_stack_shuffle)
{
- /* Phase 1 contains only character arrays. */
- expand_stack_vars (stack_protect_decl_phase_1);
+ /* Reorder decls to be protected by iterating over the variables
+ array multiple times, and allocating out of each phase in turn. */
+ /* ??? We could probably integrate this into the qsort we did
+ earlier, such that we naturally see these variables first,
+ and thus naturally allocate things in the right order. */
+ if (has_protected_decls)
+ {
+ /* Phase 1 contains only character arrays. */
+ expand_stack_vars (stack_protect_decl_phase_1);
- /* Phase 2 contains other kinds of arrays. */
- if (flag_stack_protect == 2)
- expand_stack_vars (stack_protect_decl_phase_2);
+ /* Phase 2 contains other kinds of arrays. */
+ if (flag_stack_protect == 2)
+ expand_stack_vars (stack_protect_decl_phase_2);
+ }
}
expand_stack_vars (NULL);
diff --git a/gnu/gcc/gcc/common.opt b/gnu/gcc/gcc/common.opt
index c309c43249f..49f05b92e21 100644
--- a/gnu/gcc/gcc/common.opt
+++ b/gnu/gcc/gcc/common.opt
@@ -874,6 +874,10 @@ fstack-protector-strong
Common Report RejectNegative Var(flag_stack_protect, 3)
Use a smart stack protection method for certain functions
+fstack-shuffle
+Common Report Var(flag_stack_shuffle)
+Shuffle local stack variables.
+
fstrength-reduce
Common
Does nothing. Preserved for backward compatibility.