Module Name: src Committed By: christos Date: Sun May 8 01:49:33 UTC 2011
Modified Files: src/gnu/dist/gcc4/gcc: c-common.c cfgexpand.c tree.h Log Message: Add a no_stack_protector function attribute to localize the effect of disabling stack protection on a function-by-function level, as opposed to per source file. To generate a diff of this commit: cvs rdiff -u -r1.1.1.5 -r1.2 src/gnu/dist/gcc4/gcc/c-common.c cvs rdiff -u -r1.2 -r1.3 src/gnu/dist/gcc4/gcc/cfgexpand.c cvs rdiff -u -r1.1.1.3 -r1.2 src/gnu/dist/gcc4/gcc/tree.h Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/gnu/dist/gcc4/gcc/c-common.c diff -u src/gnu/dist/gcc4/gcc/c-common.c:1.1.1.5 src/gnu/dist/gcc4/gcc/c-common.c:1.2 --- src/gnu/dist/gcc4/gcc/c-common.c:1.1.1.5 Wed Jun 20 18:56:50 2007 +++ src/gnu/dist/gcc4/gcc/c-common.c Sat May 7 21:49:32 2011 @@ -529,6 +529,8 @@ bool *); static tree handle_no_instrument_function_attribute (tree *, tree, tree, int, bool *); +static tree handle_no_stack_protector_function_attribute (tree *, tree, + tree, int, bool *); static tree handle_malloc_attribute (tree *, tree, tree, int, bool *); static tree handle_returns_twice_attribute (tree *, tree, tree, int, bool *); static tree handle_no_limit_stack_attribute (tree *, tree, tree, int, @@ -608,6 +610,8 @@ handle_weakref_attribute }, { "no_instrument_function", 0, 0, true, false, false, handle_no_instrument_function_attribute }, + { "no_stack_protector", 0, 0, true, false, false, + handle_no_stack_protector_function_attribute }, { "malloc", 0, 0, true, false, false, handle_malloc_attribute }, { "returns_twice", 0, 0, true, false, false, @@ -5051,6 +5055,32 @@ return NULL_TREE; } +/* Handle a "no_instrument_function" attribute; arguments as in + struct attribute_spec.handler. */ + +static tree +handle_no_stack_protector_function_attribute (tree *node, tree name, + tree ARG_UNUSED (args), + int ARG_UNUSED (flags), + bool *no_add_attrs) +{ + tree decl = *node; + + if (TREE_CODE (decl) != FUNCTION_DECL) + { + error ("%J%qE attribute applies only to functions", decl, name); + *no_add_attrs = true; + } + else if (DECL_INITIAL (decl)) + { + error ("%Jcan%'t set %qE attribute after definition", decl, name); + *no_add_attrs = true; + } + else + DECL_NO_STACK_PROTECTOR_FUNCTION (decl) = 1; + + return NULL_TREE; +} /* Handle a "malloc" attribute; arguments as in struct attribute_spec.handler. */ Index: src/gnu/dist/gcc4/gcc/cfgexpand.c diff -u src/gnu/dist/gcc4/gcc/cfgexpand.c:1.2 src/gnu/dist/gcc4/gcc/cfgexpand.c:1.3 --- src/gnu/dist/gcc4/gcc/cfgexpand.c:1.2 Fri Jan 26 20:27:29 2007 +++ src/gnu/dist/gcc4/gcc/cfgexpand.c Sat May 7 21:49:32 2011 @@ -862,6 +862,9 @@ unsigned int bits = stack_protect_classify_type (TREE_TYPE (decl)); int ret = 0; + if (DECL_NO_STACK_PROTECTOR_FUNCTION(decl)) + return ret; + if (bits & SPCT_HAS_SMALL_CHAR_ARRAY) has_short_buffer = true; @@ -939,6 +942,7 @@ expand_used_vars (void) { tree t, outer_block = DECL_INITIAL (current_function_decl); + bool stack_protect_func = !DECL_NO_STACK_PROTECTOR_FUNCTION (current_function_decl); /* Compute the phase of the stack frame for this function. */ { @@ -1008,7 +1012,7 @@ /* 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 && stack_protect_func) add_stack_protection_conflicts (); /* Now that we have collected all stack variables, and have computed a @@ -1020,7 +1024,8 @@ /* There are several conditions under which we should create a stack guard: protect-all, alloca used, protected decls present. */ - if (flag_stack_protect == 2 + if (stack_protect_func) + if (flag_stack_protect == 2 || (flag_stack_protect && (current_function_calls_alloca || has_protected_decls))) create_stack_guard (); @@ -1595,7 +1600,8 @@ expand_used_vars (); /* Honor stack protection warnings. */ - if (warn_stack_protect) + if (warn_stack_protect && + !DECL_NO_STACK_PROTECTOR_FUNCTION (current_function_decl)) { if (current_function_calls_alloca) warning (0, "not protecting local variables: variable length buffer"); Index: src/gnu/dist/gcc4/gcc/tree.h diff -u src/gnu/dist/gcc4/gcc/tree.h:1.1.1.3 src/gnu/dist/gcc4/gcc/tree.h:1.2 --- src/gnu/dist/gcc4/gcc/tree.h:1.1.1.3 Wed Jun 20 18:57:45 2007 +++ src/gnu/dist/gcc4/gcc/tree.h Sat May 7 21:49:32 2011 @@ -2680,6 +2680,11 @@ #define DECL_NO_INSTRUMENT_FUNCTION_ENTRY_EXIT(NODE) \ (FUNCTION_DECL_CHECK (NODE)->function_decl.no_instrument_function_entry_exit) +/* Used in FUNCTION_DECLs to indicate that the function should not be stack + protected */ +#define DECL_NO_STACK_PROTECTOR_FUNCTION(NODE) \ + (FUNCTION_DECL_CHECK (NODE)->function_decl.no_stack_protector_function) + /* Used in FUNCTION_DECLs to indicate that limit-stack-* should be disabled in this function. */ #define DECL_NO_LIMIT_STACK(NODE) \ @@ -2746,6 +2751,7 @@ unsigned regdecl_flag : 1; unsigned inline_flag : 1; unsigned no_instrument_function_entry_exit : 1; + unsigned no_stack_protector_function : 1; unsigned no_limit_stack : 1; ENUM_BITFIELD(built_in_class) built_in_class : 2;