+2015-01-14 Marcos Diaz <marcos.diaz@tallertechnologies.com>
+
+ * common.opt: New option -fstack-protector-explicit.
+ * cfgexpand.c (SPCT_FLAG_EXPLICIT): New enum.
+ (stack_protect_decl_phase): Handle stack_protect attribute for
+ explicit stack protection requests.
+ (expand_used_vars): Similarly.
+ * doc/cpp.texi (__SSP_EXPLICIT__): Document predefined macro.
+ * doc/extend.texi: Add documentation for "stack_protect" attribute.
+ * doc/invoke.texi: Add documentation for -fstack-protector-explicit.
+
2015-01-14 Oleg Endo <olegendo@gcc.gnu.org>
PR target/53988
+2015-01-14 Marcos Diaz <marcos.diaz@tallertechnologies.com>
+
+ * c-cppbuiltin.c (c_cpp_builtins): New cpp define __SSP_EXPLICIT__
+ for the new option fstack-protector_explicit.
+ * c-common.c (c_common_attribute_table): Add stack_protect attribute.
+ (handle_stack_protect_attribute): New function.
+
2015-01-13 Martin Uecker <uecker@eecs.berkeley.edu>
* c.opt: New option -Warray-bounds=.
int, bool *);
static tree handle_no_sanitize_undefined_attribute (tree *, tree, tree, int,
bool *);
+static tree handle_stack_protect_attribute (tree *, tree, tree, int, bool *);
static tree handle_noinline_attribute (tree *, tree, tree, int, bool *);
static tree handle_noclone_attribute (tree *, tree, tree, int, bool *);
static tree handle_leaf_attribute (tree *, tree, tree, int, bool *);
handle_noreturn_attribute, false },
{ "volatile", 0, 0, true, false, false,
handle_noreturn_attribute, false },
+ { "stack_protect", 0, 0, true, false, false,
+ handle_stack_protect_attribute, false },
{ "noinline", 0, 0, true, false, false,
handle_noinline_attribute, false },
{ "noclone", 0, 0, true, false, false,
return NULL_TREE;
}
+/* Handle a "stack_protect" attribute; arguments as in
+ struct attribute_spec.handler. */
+static tree
+handle_stack_protect_attribute (tree *node, tree name, tree, int,
+ bool *no_add_attrs)
+{
+ if (TREE_CODE (*node) != FUNCTION_DECL)
+ {
+ warning (OPT_Wattributes, "%qE attribute ignored", name);
+ *no_add_attrs = true;
+ }
+ else
+ DECL_ATTRIBUTES (*node)
+ = tree_cons (get_identifier ("stack_protect"),
+ NULL_TREE, DECL_ATTRIBUTES (*node));
+
+ return NULL_TREE;
+}
+
/* Handle a "noinline" attribute; arguments as in
struct attribute_spec.handler. */
/* Make the choice of the stack protector runtime visible to source code.
The macro names and values here were chosen for compatibility with an
earlier implementation, i.e. ProPolice. */
+ if (flag_stack_protect == 4)
+ cpp_define (pfile, "__SSP_EXPLICIT__=4");
if (flag_stack_protect == 3)
cpp_define (pfile, "__SSP_STRONG__=3");
if (flag_stack_protect == 2)
enum {
SPCT_FLAG_DEFAULT = 1,
SPCT_FLAG_ALL = 2,
- SPCT_FLAG_STRONG = 3
+ SPCT_FLAG_STRONG = 3,
+ SPCT_FLAG_EXPLICIT = 4
};
/* Examine TYPE and determine a bit mask of the following features. */
has_short_buffer = true;
if (flag_stack_protect == SPCT_FLAG_ALL
- || flag_stack_protect == SPCT_FLAG_STRONG)
+ || flag_stack_protect == SPCT_FLAG_STRONG
+ || (flag_stack_protect == SPCT_FLAG_EXPLICIT
+ && lookup_attribute ("stack_protect",
+ DECL_ATTRIBUTES (current_function_decl))))
{
if ((bits & (SPCT_HAS_SMALL_CHAR_ARRAY | SPCT_HAS_LARGE_CHAR_ARRAY))
&& !(bits & SPCT_HAS_AGGREGATE))
/* If stack protection is enabled, we don't share space between
vulnerable data and non-vulnerable data. */
- if (flag_stack_protect)
+ if (flag_stack_protect != 0
+ && (flag_stack_protect != SPCT_FLAG_EXPLICIT
+ || (flag_stack_protect == SPCT_FLAG_EXPLICIT
+ && lookup_attribute ("stack_protect",
+ DECL_ATTRIBUTES (current_function_decl)))))
add_stack_protection_conflicts ();
/* Now that we have collected all stack variables, and have computed a
case SPCT_FLAG_STRONG:
if (gen_stack_protect_signal
- || cfun->calls_alloca || has_protected_decls)
+ || cfun->calls_alloca || has_protected_decls
+ || lookup_attribute ("stack_protect",
+ DECL_ATTRIBUTES (current_function_decl)))
create_stack_guard ();
break;
case SPCT_FLAG_DEFAULT:
- if (cfun->calls_alloca || has_protected_decls)
+ if (cfun->calls_alloca || has_protected_decls
+ || lookup_attribute ("stack_protect",
+ DECL_ATTRIBUTES (current_function_decl)))
create_stack_guard ();
break;
+ case SPCT_FLAG_EXPLICIT:
+ if (lookup_attribute ("stack_protect",
+ DECL_ATTRIBUTES (current_function_decl)))
+ create_stack_guard ();
+ break;
default:
;
}
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
+ || flag_stack_protect == SPCT_FLAG_STRONG
+ || (flag_stack_protect == SPCT_FLAG_EXPLICIT
+ && lookup_attribute ("stack_protect",
+ DECL_ATTRIBUTES (current_function_decl))))
expand_stack_vars (stack_protect_decl_phase_2, &data);
}
Common Report RejectNegative Var(flag_stack_protect, 3)
Use a smart stack protection method for certain functions
+fstack-protector-explicit
+Common Report RejectNegative Var(flag_stack_protect, 4)
+Use stack protection method only for functions with the stack_protect attribute
+
fstack-usage
Common RejectNegative Var(flag_stack_usage)
Output stack usage information on a per-function basis
This macro is defined, with value 3, when @option{-fstack-protector-strong} is
in use.
+@item __SSP_EXPLICIT__
+This macro is defined, with value 4, when @option{-fstack-protector-explicit} is
+in use.
+
@item __SANITIZE_ADDRESS__
This macro is defined, with value 1, when @option{-fsanitize=address}
or @option{-fsanitize=kernel-address} are in use.
@code{no_sanitize_address}, @code{no_address_safety_analysis},
@code{no_sanitize_thread},
@code{no_sanitize_undefined}, @code{no_reorder}, @code{bnd_legacy},
-@code{bnd_instrument},
+@code{bnd_instrument}, @code{stack_protect},
@code{error} and @code{warning}.
Several other attributes are defined for functions on particular
target systems. Other attributes, including @code{section} are
@code{no_split_stack} attribute do not have that prologue, and thus
may run with only a small amount of stack space available.
+@item stack_protect
+@cindex @code{stack_protect} function attribute
+This function attribute make a stack protection of the function if
+flags @option{fstack-protector} or @option{fstack-protector-strong}
+or @option{fstack-protector-explicit} are set.
+
@item noinline
@cindex @code{noinline} function attribute
This function attribute prevents a function from being considered for
-fsel-sched-pipelining -fsel-sched-pipelining-outer-loops @gol
-fsemantic-interposition @gol
-fshrink-wrap -fsignaling-nans -fsingle-precision-constant @gol
--fsplit-ivs-in-unroller -fsplit-wide-types -fssa-phiopt -fstack-protector @gol
--fstack-protector-all -fstack-protector-strong -fstrict-aliasing @gol
+-fsplit-ivs-in-unroller -fsplit-wide-types -fssa-phiopt @gol
+-fstack-protector -fstack-protector-all -fstack-protector-strong @gol
+-fstack-protector-explicit -fstrict-aliasing @gol
-fstrict-overflow -fthread-jumps -ftracer -ftree-bit-ccp @gol
-ftree-builtin-call-dce -ftree-ccp -ftree-ch @gol
-ftree-coalesce-inline-vars -ftree-coalesce-vars -ftree-copy-prop @gol
be protected --- those that have local array definitions, or have
references to local frame addresses.
+@item -fstack-protector-explicit
+@opindex fstack-protector-explicit
+Like @option{-fstack-protector} but only protects those functions which
+have the @code{stack_protect} attribute
+
@item -fsection-anchors
@opindex fsection-anchors
Try to reduce the number of symbolic address calculations by using
+2015-01-14 Marcos Diaz <marcos.diaz@tallertechnologies.com>
+
+ * gcc.dg/stackprotectexplicit1.c: New test.
+ * g++.dg/stackprotectexplicit2.c: New test.
+
2015-01-14 Jerry DeLisle <jvdelisle@gcc.gnu.org>
PR target/61933
--- /dev/null
+/* Test that stack protection is done on chosen functions. */
+
+/* { dg-do compile { target i?86-*-* x86_64-*-* } } */
+/* { dg-options "-O2 -fstack-protector-explicit" } */
+
+int A()
+{
+ int A[23];
+ char b[22];
+}
+
+int __attribute__((stack_protect)) B()
+{
+ int a;
+ int b;
+ return a+b;
+}
+
+int __attribute__((stack_protect)) c()
+{
+ int a;
+ char b[34];
+ return 0;
+}
+
+
+/* { dg-final { scan-assembler-times "stack_chk_fail" 2 } } */
\ No newline at end of file
--- /dev/null
+/* { dg-do run { target native } } */
+/* { dg-options "-fstack-protector-explicit" } */
+/* { dg-require-effective-target fstack_protector } */
+
+#include <stdlib.h>
+
+void
+__stack_chk_fail (void)
+{
+ exit (0); /* pass */
+}
+
+int __attribute__((stack_protect)) main ()
+{
+ int i;
+ char foo[255];
+
+ // smash stack
+ for (i = 0; i <= 400; i++)
+ foo[i] = 42;
+
+ return 1; /* fail */
+}