aboutsummaryrefslogtreecommitdiff
path: root/gcc/varasm.c
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2012-11-12 15:52:42 +0000
committerDodji Seketeli <dodji@redhat.com>2012-11-12 15:52:42 +0000
commitfcd310277b672002a1671cc098265fc1f74955ff (patch)
tree18be1f25e100232473bd95eeef5508dbb137f634 /gcc/varasm.c
parentd179bcdce7be348bd17f4434f46a2dc3e5bd9d69 (diff)
Implement protection of global variables
This patch implements the protection of global variables. See the comments appended to the beginning of the asan.c file. * varasm.c: Include asan.h. (assemble_noswitch_variable): Grow size by asan_red_zone_size if decl is asan protected. (place_block_symbol): Likewise. (assemble_variable): If decl is asan protected, increase DECL_ALIGN if needed, and for decls emitted using assemble_variable_contents append padding zeros after it. * Makefile.in (varasm.o): Depend on asan.h. * asan.c: Include output.h. (asan_pp, asan_pp_initialized, asan_ctor_statements): New variables. (asan_pp_initialize, asan_pp_string): New functions. (asan_emit_stack_protection): Use asan_pp{,_initialized} instead of local pp{,_initialized} vars, use asan_pp_initialize and asan_pp_string helpers. (asan_needs_local_alias, asan_protect_global, asan_global_struct, asan_add_global): New functions. (asan_finish_file): Protect global vars that can be protected. Use asan_ctor_statements instead of ctor_statements * asan.h (asan_protect_global): New prototype. (asan_red_zone_size): New inline function. git-svn-id: https://gcc.gnu.org/svn/gcc/trunk@193437 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/varasm.c')
-rw-r--r--gcc/varasm.c22
1 files changed, 22 insertions, 0 deletions
diff --git a/gcc/varasm.c b/gcc/varasm.c
index b3003485423..641ce0c43e8 100644
--- a/gcc/varasm.c
+++ b/gcc/varasm.c
@@ -51,6 +51,7 @@ along with GCC; see the file COPYING3. If not see
#include "tree-mudflap.h"
#include "cgraph.h"
#include "pointer-set.h"
+#include "asan.h"
#ifdef XCOFF_DEBUGGING_INFO
#include "xcoffout.h" /* Needed for external data
@@ -1831,6 +1832,9 @@ assemble_noswitch_variable (tree decl, const char *name, section *sect)
size = tree_low_cst (DECL_SIZE_UNIT (decl), 1);
rounded = size;
+ if (flag_asan && asan_protect_global (decl))
+ size += asan_red_zone_size (size);
+
/* Don't allocate zero bytes of common,
since that means "undefined external" in the linker. */
if (size == 0)
@@ -1897,6 +1901,7 @@ assemble_variable (tree decl, int top_level ATTRIBUTE_UNUSED,
const char *name;
rtx decl_rtl, symbol;
section *sect;
+ bool asan_protected = false;
/* This function is supposed to handle VARIABLES. Ensure we have one. */
gcc_assert (TREE_CODE (decl) == VAR_DECL);
@@ -1984,6 +1989,15 @@ assemble_variable (tree decl, int top_level ATTRIBUTE_UNUSED,
/* Compute the alignment of this data. */
align_variable (decl, dont_output_data);
+
+ if (flag_asan
+ && asan_protect_global (decl))
+ {
+ asan_protected = true;
+ DECL_ALIGN (decl) = MAX (DECL_ALIGN (decl),
+ ASAN_RED_ZONE_SIZE * BITS_PER_UNIT);
+ }
+
set_mem_align (decl_rtl, DECL_ALIGN (decl));
if (TREE_PUBLIC (decl))
@@ -2022,6 +2036,12 @@ assemble_variable (tree decl, int top_level ATTRIBUTE_UNUSED,
if (DECL_ALIGN (decl) > BITS_PER_UNIT)
ASM_OUTPUT_ALIGN (asm_out_file, floor_log2 (DECL_ALIGN_UNIT (decl)));
assemble_variable_contents (decl, name, dont_output_data);
+ if (asan_protected)
+ {
+ unsigned HOST_WIDE_INT int size
+ = tree_low_cst (DECL_SIZE_UNIT (decl), 1);
+ assemble_zeros (asan_red_zone_size (size));
+ }
}
}
@@ -6926,6 +6946,8 @@ place_block_symbol (rtx symbol)
decl = SYMBOL_REF_DECL (symbol);
alignment = DECL_ALIGN (decl);
size = tree_low_cst (DECL_SIZE_UNIT (decl), 1);
+ if (flag_asan && asan_protect_global (decl))
+ size += asan_red_zone_size (size);
}
/* Calculate the object's offset from the start of the block. */