aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorMarcos Diaz <marcos.diaz@tallertechnologies.com>2015-01-15 05:29:12 +0000
committerJeff Law <law@gcc.gnu.org>2015-01-14 22:29:12 -0700
commit5434dc0730795cf6a2ef8a9fe20e4dcc9cd077be (patch)
tree491382b1163238c05c384ce06c8581bc06d76bfb /gcc
parent1a0c69834516bf7731d34aa47febea6850ed773f (diff)
downloadgcc-5434dc0730795cf6a2ef8a9fe20e4dcc9cd077be.zip
gcc-5434dc0730795cf6a2ef8a9fe20e4dcc9cd077be.tar.gz
gcc-5434dc0730795cf6a2ef8a9fe20e4dcc9cd077be.tar.bz2
common.opt: New option -fstack-protector-explicit.
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. * 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. * gcc.dg/stackprotectexplicit1.c: New test. * g++.dg/stackprotectexplicit2.c: New test. From-SVN: r219633
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog11
-rw-r--r--gcc/c-family/ChangeLog7
-rw-r--r--gcc/c-family/c-common.c22
-rw-r--r--gcc/c-family/c-cppbuiltin.c2
-rw-r--r--gcc/cfgexpand.c33
-rw-r--r--gcc/common.opt4
-rw-r--r--gcc/doc/cpp.texi4
-rw-r--r--gcc/doc/extend.texi8
-rw-r--r--gcc/doc/invoke.texi10
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/g++.dg/stackprotectexplicit2.C27
-rw-r--r--gcc/testsuite/gcc.dg/stackprotectexplicit1.c23
12 files changed, 147 insertions, 9 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 5e959c2..701c6c6 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,14 @@
+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
diff --git a/gcc/c-family/ChangeLog b/gcc/c-family/ChangeLog
index 1efb75a..9764045 100644
--- a/gcc/c-family/ChangeLog
+++ b/gcc/c-family/ChangeLog
@@ -1,3 +1,10 @@
+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=.
diff --git a/gcc/c-family/c-common.c b/gcc/c-family/c-common.c
index 29cab01..054f5a0 100644
--- a/gcc/c-family/c-common.c
+++ b/gcc/c-family/c-common.c
@@ -327,6 +327,7 @@ static tree handle_no_address_safety_analysis_attribute (tree *, tree, tree,
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 *);
@@ -657,6 +658,8 @@ const struct attribute_spec c_common_attribute_table[] =
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,
@@ -6769,6 +6772,25 @@ handle_no_sanitize_undefined_attribute (tree *node, tree name, tree, int,
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. */
diff --git a/gcc/c-family/c-cppbuiltin.c b/gcc/c-family/c-cppbuiltin.c
index 229a316..0b00d59 100644
--- a/gcc/c-family/c-cppbuiltin.c
+++ b/gcc/c-family/c-cppbuiltin.c
@@ -1212,6 +1212,8 @@ c_cpp_builtins (cpp_reader *pfile)
/* 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)
diff --git a/gcc/cfgexpand.c b/gcc/cfgexpand.c
index 8926e8f..c92c786 100644
--- a/gcc/cfgexpand.c
+++ b/gcc/cfgexpand.c
@@ -1411,7 +1411,8 @@ clear_tree_used (tree block)
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. */
@@ -1484,7 +1485,10 @@ stack_protect_decl_phase (tree decl)
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))
@@ -1859,7 +1863,11 @@ expand_used_vars (void)
/* 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
@@ -1877,15 +1885,24 @@ expand_used_vars (void)
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:
;
}
@@ -1911,7 +1928,11 @@ expand_used_vars (void)
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);
}
diff --git a/gcc/common.opt b/gcc/common.opt
index 3d19875..c321960 100644
--- a/gcc/common.opt
+++ b/gcc/common.opt
@@ -2093,6 +2093,10 @@ fstack-protector-strong
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
diff --git a/gcc/doc/cpp.texi b/gcc/doc/cpp.texi
index e94bdf7..10b72e7 100644
--- a/gcc/doc/cpp.texi
+++ b/gcc/doc/cpp.texi
@@ -2351,6 +2351,10 @@ in use.
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.
diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi
index 942a6bc..bf6d710 100644
--- a/gcc/doc/extend.texi
+++ b/gcc/doc/extend.texi
@@ -2207,7 +2207,7 @@ attributes are currently defined for functions on all targets:
@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
@@ -3444,6 +3444,12 @@ prologue which decides whether to split the stack. Functions with the
@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
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index 748c70a..638ed9a 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -428,8 +428,9 @@ Objective-C and Objective-C++ Dialects}.
-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
@@ -9838,6 +9839,11 @@ Like @option{-fstack-protector} but includes additional functions to
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
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 4be48a1..1c53160 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+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
diff --git a/gcc/testsuite/g++.dg/stackprotectexplicit2.C b/gcc/testsuite/g++.dg/stackprotectexplicit2.C
new file mode 100644
index 0000000..9cf9ab9
--- /dev/null
+++ b/gcc/testsuite/g++.dg/stackprotectexplicit2.C
@@ -0,0 +1,27 @@
+/* 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
diff --git a/gcc/testsuite/gcc.dg/stackprotectexplicit1.c b/gcc/testsuite/gcc.dg/stackprotectexplicit1.c
new file mode 100644
index 0000000..658c297
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/stackprotectexplicit1.c
@@ -0,0 +1,23 @@
+/* { 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 */
+}