diff options
-rw-r--r-- | gnu/gcc/gcc/cfgexpand.c | 41 | ||||
-rw-r--r-- | gnu/gcc/gcc/common.opt | 4 |
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. |