5fea0d9894
lang/gcc. PR: 203751, 186852 [1] Submitted by: software-freebsd@interfasys.ch [1]
157 lines
4.6 KiB
Text
157 lines
4.6 KiB
Text
--- gcc/cfgexpand.c.orig
|
|
+++ gcc/cfgexpand.c
|
|
@@ -1291,6 +1291,12 @@
|
|
clear_tree_used (t);
|
|
}
|
|
|
|
+ enum {
|
|
+ SPCT_FLAG_DEFAULT = 1,
|
|
+ SPCT_FLAG_ALL = 2,
|
|
+ SPCT_FLAG_STRONG = 3
|
|
+ };
|
|
+
|
|
/* Examine TYPE and determine a bit mask of the following features. */
|
|
|
|
#define SPCT_HAS_LARGE_CHAR_ARRAY 1
|
|
@@ -1360,7 +1366,8 @@
|
|
if (bits & SPCT_HAS_SMALL_CHAR_ARRAY)
|
|
has_short_buffer = true;
|
|
|
|
- if (flag_stack_protect == 2)
|
|
+ if (flag_stack_protect == SPCT_FLAG_ALL
|
|
+ || flag_stack_protect == SPCT_FLAG_STRONG)
|
|
{
|
|
if ((bits & (SPCT_HAS_SMALL_CHAR_ARRAY | SPCT_HAS_LARGE_CHAR_ARRAY))
|
|
&& !(bits & SPCT_HAS_AGGREGATE))
|
|
@@ -1514,6 +1521,27 @@
|
|
return size;
|
|
}
|
|
|
|
+/* Helper routine to check if a record or union contains an array field. */
|
|
+
|
|
+static int
|
|
+record_or_union_type_has_array_p (const_tree tree_type)
|
|
+{
|
|
+ tree fields = TYPE_FIELDS (tree_type);
|
|
+ tree f;
|
|
+
|
|
+ for (f = fields; f; f = DECL_CHAIN (f))
|
|
+ if (TREE_CODE (f) == FIELD_DECL)
|
|
+ {
|
|
+ tree field_type = TREE_TYPE (f);
|
|
+ if (RECORD_OR_UNION_TYPE_P (field_type)
|
|
+ && record_or_union_type_has_array_p (field_type))
|
|
+ return 1;
|
|
+ if (TREE_CODE (field_type) == ARRAY_TYPE)
|
|
+ return 1;
|
|
+ }
|
|
+ return 0;
|
|
+}
|
|
+
|
|
/* Expand all variables used in the function. */
|
|
|
|
static rtx
|
|
@@ -1525,6 +1553,7 @@
|
|
struct pointer_map_t *ssa_name_decls;
|
|
unsigned i;
|
|
unsigned len;
|
|
+ bool gen_stack_protect_signal = false;
|
|
|
|
/* Compute the phase of the stack frame for this function. */
|
|
{
|
|
@@ -1575,6 +1604,24 @@
|
|
}
|
|
}
|
|
pointer_map_destroy (ssa_name_decls);
|
|
+
|
|
+ if (flag_stack_protect == SPCT_FLAG_STRONG)
|
|
+ FOR_EACH_LOCAL_DECL (cfun, i, var)
|
|
+ if (!is_global_var (var))
|
|
+ {
|
|
+ tree var_type = TREE_TYPE (var);
|
|
+ /* Examine local referenced variables that have their addresses taken,
|
|
+ contain an array, or are arrays. */
|
|
+ if (TREE_CODE (var) == VAR_DECL
|
|
+ && (TREE_CODE (var_type) == ARRAY_TYPE
|
|
+ || TREE_ADDRESSABLE (var)
|
|
+ || (RECORD_OR_UNION_TYPE_P (var_type)
|
|
+ && record_or_union_type_has_array_p (var_type))))
|
|
+ {
|
|
+ gen_stack_protect_signal = true;
|
|
+ break;
|
|
+ }
|
|
+ }
|
|
|
|
/* At this point all variables on the local_decls with TREE_USED
|
|
set are not associated with any block scope. Lay them out. */
|
|
@@ -1662,12 +1709,32 @@
|
|
dump_stack_var_partition ();
|
|
}
|
|
|
|
- /* There are several conditions under which we should create a
|
|
- stack guard: protect-all, alloca used, protected decls present. */
|
|
- if (flag_stack_protect == 2
|
|
- || (flag_stack_protect
|
|
- && (cfun->calls_alloca || has_protected_decls)))
|
|
- create_stack_guard ();
|
|
+ /* Create stack guard, if
|
|
+ a) "-fstack-protector-all" - always;
|
|
+ b) "-fstack-protector-strong" - if there are arrays, memory
|
|
+ references to local variables, alloca used, or protected decls present;
|
|
+ c) "-fstack-protector" - if alloca used, or protected decls present */
|
|
+
|
|
+ switch (flag_stack_protect)
|
|
+ {
|
|
+ case SPCT_FLAG_ALL:
|
|
+ create_stack_guard ();
|
|
+ break;
|
|
+
|
|
+ case SPCT_FLAG_STRONG:
|
|
+ if (gen_stack_protect_signal
|
|
+ || cfun->calls_alloca || has_protected_decls)
|
|
+ create_stack_guard ();
|
|
+ break;
|
|
+
|
|
+ case SPCT_FLAG_DEFAULT:
|
|
+ if (cfun->calls_alloca || has_protected_decls)
|
|
+ create_stack_guard ();
|
|
+ break;
|
|
+
|
|
+ default:
|
|
+ ;
|
|
+ }
|
|
|
|
/* Assign rtl to each variable based on these partitions. */
|
|
if (stack_vars_num > 0)
|
|
@@ -1688,7 +1755,7 @@
|
|
expand_stack_vars (stack_protect_decl_phase_1, &data);
|
|
|
|
/* Phase 2 contains other kinds of arrays. */
|
|
- if (flag_stack_protect == 2)
|
|
+ if (flag_stack_protect == SPCT_FLAG_ALL)
|
|
expand_stack_vars (stack_protect_decl_phase_2, &data);
|
|
}
|
|
|
|
--- gcc/common.opt.orig
|
|
+++ gcc/common.opt
|
|
@@ -1942,6 +1942,10 @@ fstack-protector-all
|
|
Common Report RejectNegative Var(flag_stack_protect, 2)
|
|
Use a stack protection method for every function
|
|
|
|
+fstack-protector-strong
|
|
+Common Report RejectNegative Var(flag_stack_protect, 3)
|
|
+Use a smart stack protection method for certain functions
|
|
+
|
|
fstack-usage
|
|
Common RejectNegative Var(flag_stack_usage)
|
|
Output stack usage information on a per-function basis
|
|
--- gcc/gcc.c.orig
|
|
+++ gcc/gcc.c
|
|
@@ -655,7 +655,7 @@ proper position among the other output files. */
|
|
#ifdef TARGET_LIBC_PROVIDES_SSP
|
|
#define LINK_SSP_SPEC "%{fstack-protector:}"
|
|
#else
|
|
-#define LINK_SSP_SPEC "%{fstack-protector|fstack-protector-all:-lssp_nonshared -lssp}"
|
|
+#define LINK_SSP_SPEC "%{fstack-protector|fstack-protector-strong|fstack-protector-all:-lssp_nonshared -lssp}"
|
|
#endif
|
|
#endif
|