From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 31406 invoked by alias); 12 Nov 2012 11:32:19 -0000 Received: (qmail 31398 invoked by uid 22791); 12 Nov 2012 11:32:19 -0000 X-SWARE-Spam-Status: No, hits=-4.3 required=5.0 tests=AWL,BAYES_20,KAM_STOCKGEN,KHOP_RCVD_UNTRUST,RCVD_IN_DNSWL_HI,RP_MATCHES_RCVD,SPF_HELO_PASS,TW_SV X-Spam-Check-By: sourceware.org Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Mon, 12 Nov 2012 11:32:11 +0000 Received: from int-mx02.intmail.prod.int.phx2.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id qACBWAtW025740 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Mon, 12 Nov 2012 06:32:10 -0500 Received: from localhost (ovpn-116-79.ams2.redhat.com [10.36.116.79]) by int-mx02.intmail.prod.int.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id qACBW9PJ016292 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO); Mon, 12 Nov 2012 06:32:10 -0500 Received: by localhost (Postfix, from userid 1000) id B7D092C0104; Mon, 12 Nov 2012 12:32:08 +0100 (CET) From: Dodji Seketeli To: Diego Novillo Cc: gcc-patches@gcc.gnu.org, jakub@redhat.com, wmi@google.com, davidxl@google.com, konstantin.s.serebryany@gmail.com Subject: Re: [PATCH 06/10] Implement protection of global variables References: <1351799566-31447-1-git-send-email-dodji@redhat.com> <87pq3v8vmi.fsf@redhat.com> <87wqy37gor.fsf_-_@redhat.com> <5099486E.2000409@google.com> X-URL: http://www.redhat.com Date: Mon, 12 Nov 2012 11:32:00 -0000 In-Reply-To: <5099486E.2000409@google.com> (Diego Novillo's message of "Tue, 06 Nov 2012 09:27:10 -0800") Message-ID: <87haov3vlz.fsf@redhat.com> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/24.1 (gnu/linux) MIME-Version: 1.0 Content-Type: text/plain Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org X-SW-Source: 2012-11/txt/msg00894.txt.bz2 Diego Novillo writes: > On 2012-11-02 16:01 , Dodji Seketeli wrote: > > > * 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. > > OK. Thanks. > Please, also put the high-level description in asan.c's documentation. Done. Below is the updated patch. 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: svn+ssh://gcc.gnu.org/svn/gcc/branches/asan@192541 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ChangeLog.asan | 24 ++++ gcc/Makefile.in | 2 +- gcc/asan.c | 344 +++++++++++++++++++++++++++++++++++++++++++++++------ gcc/asan.h | 11 ++ gcc/varasm.c | 22 ++++ 5 files changed, 365 insertions(+), 38 deletions(-) * Makefile.in (asan.o): Depend on $(EXPR_H) $(OPTABS_H). (cfgexpand.o): Depend on asan.h. diff --git a/gcc/Makefile.in b/gcc/Makefile.in index 7a0b074..83a424e 100644 --- a/gcc/Makefile.in +++ b/gcc/Makefile.in @@ -2719,7 +2719,7 @@ varasm.o : varasm.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) \ output.h $(DIAGNOSTIC_CORE_H) xcoffout.h debug.h $(GGC_H) $(TM_P_H) \ $(HASHTAB_H) $(TARGET_H) langhooks.h gt-varasm.h $(BASIC_BLOCK_H) \ $(CGRAPH_H) $(TARGET_DEF_H) tree-mudflap.h \ - pointer-set.h $(COMMON_TARGET_H) + pointer-set.h $(COMMON_TARGET_H) asan.h function.o : function.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_ERROR_H) \ $(TREE_H) $(GIMPLE_H) $(FLAGS_H) $(FUNCTION_H) $(EXPR_H) \ $(OPTABS_H) $(LIBFUNCS_H) $(REGS_H) hard-reg-set.h insn-config.h $(RECOG_H) \ diff --git a/gcc/asan.c b/gcc/asan.c index a3bb47b..c88f59d 100644 --- a/gcc/asan.c +++ b/gcc/asan.c @@ -31,6 +31,7 @@ along with GCC; see the file COPYING3. If not see #include "target.h" #include "expr.h" #include "optabs.h" +#include "output.h" /* AddressSanitizer finds out-of-bounds and use-after-free bugs @@ -166,7 +167,43 @@ along with GCC; see the file COPYING3. If not see non-accessible) the regions of the red zones and mark the regions of stack variables as accessible, and emit some epilogue code to un-poison (mark as accessible) the regions of red zones right before - the function exits. */ + the function exits. + + [Protection of global variables] + + The basic idea is to insert a red zone between two global variables + and install a constructor function that calls the asan runtime to do + the populating of the relevant shadow memory regions at load time. + + So the global variables are laid out as to insert a red zone between + them. The size of the red zones is so that each variable starts on a + 32 bytes boundary. + + Then a constructor function is installed so that, for each global + variable, it calls the runtime asan library function + __asan_register_globals_with an instance of this type: + + struct __asan_global + { + // Address of the beginning of the global variable. + const void *__beg; + + // Initial size of the global variable. + uptr __size; + + // Size of the global variable + size of the red zone. This + // size is 32 bytes aligned. + uptr __size_with_redzone; + + // Name of the global variable. + const void *__name; + + // This is always set to NULL for now. + uptr __has_dynamic_init; + } + + A destructor function that calls the runtime asan library function + _asan_unregister_globals is also installed. */ alias_set_type asan_shadow_set = -1; @@ -174,6 +211,34 @@ alias_set_type asan_shadow_set = -1; alias set is used for all shadow memory accesses. */ static GTY(()) tree shadow_ptr_types[2]; +/* Asan pretty-printer, used for buidling of the description STRING_CSTs. */ +static pretty_printer asan_pp; +static bool asan_pp_initialized; + +/* Initialize asan_pp. */ + +static void +asan_pp_initialize (void) +{ + pp_construct (&asan_pp, /* prefix */NULL, /* line-width */0); + asan_pp_initialized = true; +} + +/* Create ADDR_EXPR of STRING_CST with asan_pp text. */ + +static tree +asan_pp_string (void) +{ + const char *buf = pp_base_formatted_text (&asan_pp); + size_t len = strlen (buf); + tree ret = build_string (len + 1, buf); + TREE_TYPE (ret) + = build_array_type (char_type_node, build_index_type (size_int (len))); + TREE_READONLY (ret) = 1; + TREE_STATIC (ret) = 1; + return build1 (ADDR_EXPR, build_pointer_type (char_type_node), ret); +} + /* Return a CONST_INT representing 4 subsequent shadow memory bytes. */ static rtx @@ -208,51 +273,38 @@ asan_emit_stack_protection (rtx base, HOST_WIDE_INT *offsets, tree *decls, HOST_WIDE_INT last_offset, last_size; int l; unsigned char cur_shadow_byte = ASAN_STACK_MAGIC_LEFT; - static pretty_printer pp; - static bool pp_initialized; - const char *buf; - size_t len; tree str_cst; /* First of all, prepare the description string. */ - if (!pp_initialized) - { - pp_construct (&pp, /* prefix */NULL, /* line-width */0); - pp_initialized = true; - } - pp_clear_output_area (&pp); + if (!asan_pp_initialized) + asan_pp_initialize (); + + pp_clear_output_area (&asan_pp); if (DECL_NAME (current_function_decl)) - pp_base_tree_identifier (&pp, DECL_NAME (current_function_decl)); + pp_base_tree_identifier (&asan_pp, DECL_NAME (current_function_decl)); else - pp_string (&pp, ""); - pp_space (&pp); - pp_decimal_int (&pp, length / 2 - 1); - pp_space (&pp); + pp_string (&asan_pp, ""); + pp_space (&asan_pp); + pp_decimal_int (&asan_pp, length / 2 - 1); + pp_space (&asan_pp); for (l = length - 2; l; l -= 2) { tree decl = decls[l / 2 - 1]; - pp_wide_integer (&pp, offsets[l] - base_offset); - pp_space (&pp); - pp_wide_integer (&pp, offsets[l - 1] - offsets[l]); - pp_space (&pp); + pp_wide_integer (&asan_pp, offsets[l] - base_offset); + pp_space (&asan_pp); + pp_wide_integer (&asan_pp, offsets[l - 1] - offsets[l]); + pp_space (&asan_pp); if (DECL_P (decl) && DECL_NAME (decl)) { - pp_decimal_int (&pp, IDENTIFIER_LENGTH (DECL_NAME (decl))); - pp_space (&pp); - pp_base_tree_identifier (&pp, DECL_NAME (decl)); + pp_decimal_int (&asan_pp, IDENTIFIER_LENGTH (DECL_NAME (decl))); + pp_space (&asan_pp); + pp_base_tree_identifier (&asan_pp, DECL_NAME (decl)); } else - pp_string (&pp, "9 "); - pp_space (&pp); + pp_string (&asan_pp, "9 "); + pp_space (&asan_pp); } - buf = pp_base_formatted_text (&pp); - len = strlen (buf); - str_cst = build_string (len + 1, buf); - TREE_TYPE (str_cst) - = build_array_type (char_type_node, build_index_type (size_int (len))); - TREE_READONLY (str_cst) = 1; - TREE_STATIC (str_cst) = 1; - str_cst = build1 (ADDR_EXPR, build_pointer_type (char_type_node), str_cst); + str_cst = asan_pp_string (); /* Emit the prologue sequence. */ base = expand_binop (Pmode, add_optab, base, GEN_INT (base_offset), @@ -357,6 +409,75 @@ asan_emit_stack_protection (rtx base, HOST_WIDE_INT *offsets, tree *decls, return ret; } +/* Return true if DECL, a global var, might be overridden and needs + therefore a local alias. */ + +static bool +asan_needs_local_alias (tree decl) +{ + return DECL_WEAK (decl) || !targetm.binds_local_p (decl); +} + +/* Return true if DECL is a VAR_DECL that should be protected + by Address Sanitizer, by appending a red zone with protected + shadow memory after it and aligning it to at least + ASAN_RED_ZONE_SIZE bytes. */ + +bool +asan_protect_global (tree decl) +{ + rtx rtl, symbol; + section *sect; + + if (TREE_CODE (decl) != VAR_DECL + /* TLS vars aren't statically protectable. */ + || DECL_THREAD_LOCAL_P (decl) + /* Externs will be protected elsewhere. */ + || DECL_EXTERNAL (decl) + || !TREE_ASM_WRITTEN (decl) + || !DECL_RTL_SET_P (decl) + /* Comdat vars pose an ABI problem, we can't know if + the var that is selected by the linker will have + padding or not. */ + || DECL_ONE_ONLY (decl) + /* Similarly for common vars. People can use -fno-common. */ + || DECL_COMMON (decl) + /* Don't protect if using user section, often vars placed + into user section from multiple TUs are then assumed + to be an array of such vars, putting padding in there + breaks this assumption. */ + || (DECL_SECTION_NAME (decl) != NULL_TREE + && !DECL_HAS_IMPLICIT_SECTION_NAME_P (decl)) + || DECL_SIZE (decl) == 0 + || ASAN_RED_ZONE_SIZE * BITS_PER_UNIT > MAX_OFILE_ALIGNMENT + || !valid_constant_size_p (DECL_SIZE_UNIT (decl)) + || DECL_ALIGN_UNIT (decl) > 2 * ASAN_RED_ZONE_SIZE) + return false; + + rtl = DECL_RTL (decl); + if (!MEM_P (rtl) || GET_CODE (XEXP (rtl, 0)) != SYMBOL_REF) + return false; + symbol = XEXP (rtl, 0); + + if (CONSTANT_POOL_ADDRESS_P (symbol) + || TREE_CONSTANT_POOL_ADDRESS_P (symbol)) + return false; + + sect = get_variable_section (decl, false); + if (sect->common.flags & SECTION_COMMON) + return false; + + if (lookup_attribute ("weakref", DECL_ATTRIBUTES (decl))) + return false; + +#ifndef ASM_OUTPUT_DEF + if (asan_needs_local_alias (decl)) + return false; +#endif + + return true; +} + /* Construct a function tree for __asan_report_{load,store}{1,2,4,8,16}. IS_STORE is either 1 (for a store) or 0 (for a load). SIZE_IN_BYTES is one of 1, 2, 4, 8, 16. */ @@ -657,6 +778,105 @@ transform_statements (void) } } +/* Build + struct __asan_global + { + const void *__beg; + uptr __size; + uptr __size_with_redzone; + const void *__name; + uptr __has_dynamic_init; + } type. */ + +static tree +asan_global_struct (void) +{ + static const char *field_names[5] + = { "__beg", "__size", "__size_with_redzone", + "__name", "__has_dynamic_init" }; + tree fields[5], ret; + int i; + + ret = make_node (RECORD_TYPE); + for (i = 0; i < 5; i++) + { + fields[i] + = build_decl (UNKNOWN_LOCATION, FIELD_DECL, + get_identifier (field_names[i]), + (i == 0 || i == 3) ? const_ptr_type_node + : build_nonstandard_integer_type (POINTER_SIZE, 1)); + DECL_CONTEXT (fields[i]) = ret; + if (i) + DECL_CHAIN (fields[i - 1]) = fields[i]; + } + TYPE_FIELDS (ret) = fields[0]; + TYPE_NAME (ret) = get_identifier ("__asan_global"); + layout_type (ret); + return ret; +} + +/* Append description of a single global DECL into vector V. + TYPE is __asan_global struct type as returned by asan_global_struct. */ + +static void +asan_add_global (tree decl, tree type, VEC(constructor_elt, gc) *v) +{ + tree init, uptr = TREE_TYPE (DECL_CHAIN (TYPE_FIELDS (type))); + unsigned HOST_WIDE_INT size; + tree str_cst, refdecl = decl; + VEC(constructor_elt, gc) *vinner = NULL; + + if (!asan_pp_initialized) + asan_pp_initialize (); + + pp_clear_output_area (&asan_pp); + if (DECL_NAME (decl)) + pp_base_tree_identifier (&asan_pp, DECL_NAME (decl)); + else + pp_string (&asan_pp, ""); + pp_space (&asan_pp); + pp_left_paren (&asan_pp); + pp_string (&asan_pp, main_input_filename); + pp_right_paren (&asan_pp); + str_cst = asan_pp_string (); + + if (asan_needs_local_alias (decl)) + { + char buf[20]; + ASM_GENERATE_INTERNAL_LABEL (buf, "LASAN", + VEC_length (constructor_elt, v) + 1); + refdecl = build_decl (DECL_SOURCE_LOCATION (decl), + VAR_DECL, get_identifier (buf), TREE_TYPE (decl)); + TREE_ADDRESSABLE (refdecl) = TREE_ADDRESSABLE (decl); + TREE_READONLY (refdecl) = TREE_READONLY (decl); + TREE_THIS_VOLATILE (refdecl) = TREE_THIS_VOLATILE (decl); + DECL_GIMPLE_REG_P (refdecl) = DECL_GIMPLE_REG_P (decl); + DECL_ARTIFICIAL (refdecl) = DECL_ARTIFICIAL (decl); + DECL_IGNORED_P (refdecl) = DECL_IGNORED_P (decl); + TREE_STATIC (refdecl) = 1; + TREE_PUBLIC (refdecl) = 0; + TREE_USED (refdecl) = 1; + assemble_alias (refdecl, DECL_ASSEMBLER_NAME (decl)); + } + + CONSTRUCTOR_APPEND_ELT (vinner, NULL_TREE, + fold_convert (const_ptr_type_node, + build_fold_addr_expr (refdecl))); + size = tree_low_cst (DECL_SIZE_UNIT (decl), 1); + CONSTRUCTOR_APPEND_ELT (vinner, NULL_TREE, build_int_cst (uptr, size)); + size += asan_red_zone_size (size); + CONSTRUCTOR_APPEND_ELT (vinner, NULL_TREE, build_int_cst (uptr, size)); + CONSTRUCTOR_APPEND_ELT (vinner, NULL_TREE, + fold_convert (const_ptr_type_node, str_cst)); + CONSTRUCTOR_APPEND_ELT (vinner, NULL_TREE, build_int_cst (uptr, 0)); + init = build_constructor (type, vinner); + CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, init); +} + +/* Needs to be GTY(()), because cgraph_build_static_cdtor may + invoke ggc_collect. */ +static GTY(()) tree asan_ctor_statements; + /* Module-level instrumentation. - Insert __asan_init() into the list of CTORs. - TODO: insert redzones around globals. @@ -665,11 +885,61 @@ transform_statements (void) void asan_finish_file (void) { - tree ctor_statements = NULL_TREE; + struct varpool_node *vnode; + unsigned HOST_WIDE_INT gcount = 0; + append_to_statement_list (build_call_expr (asan_init_func (), 0), - &ctor_statements); - cgraph_build_static_cdtor ('I', ctor_statements, - MAX_RESERVED_INIT_PRIORITY - 1); + &asan_ctor_statements); + FOR_EACH_DEFINED_VARIABLE (vnode) + if (asan_protect_global (vnode->symbol.decl)) + ++gcount; + if (gcount) + { + tree type = asan_global_struct (), var, ctor, decl; + tree uptr = build_nonstandard_integer_type (POINTER_SIZE, 1); + tree dtor_statements = NULL_TREE; + VEC(constructor_elt, gc) *v; + char buf[20]; + + type = build_array_type_nelts (type, gcount); + ASM_GENERATE_INTERNAL_LABEL (buf, "LASAN", 0); + var = build_decl (UNKNOWN_LOCATION, VAR_DECL, get_identifier (buf), + type); + TREE_STATIC (var) = 1; + TREE_PUBLIC (var) = 0; + DECL_ARTIFICIAL (var) = 1; + DECL_IGNORED_P (var) = 1; + v = VEC_alloc (constructor_elt, gc, gcount); + FOR_EACH_DEFINED_VARIABLE (vnode) + if (asan_protect_global (vnode->symbol.decl)) + asan_add_global (vnode->symbol.decl, TREE_TYPE (type), v); + ctor = build_constructor (type, v); + TREE_CONSTANT (ctor) = 1; + TREE_STATIC (ctor) = 1; + DECL_INITIAL (var) = ctor; + varpool_assemble_decl (varpool_node_for_decl (var)); + + type = build_function_type_list (void_type_node, + build_pointer_type (TREE_TYPE (type)), + uptr, NULL_TREE); + decl = build_fn_decl ("__asan_register_globals", type); + TREE_NOTHROW (decl) = 1; + append_to_statement_list (build_call_expr (decl, 2, + build_fold_addr_expr (var), + build_int_cst (uptr, gcount)), + &asan_ctor_statements); + + decl = build_fn_decl ("__asan_unregister_globals", type); + TREE_NOTHROW (decl) = 1; + append_to_statement_list (build_call_expr (decl, 2, + build_fold_addr_expr (var), + build_int_cst (uptr, gcount)), + &dtor_statements); + cgraph_build_static_cdtor ('D', dtor_statements, + MAX_RESERVED_INIT_PRIORITY - 1); + } + cgraph_build_static_cdtor ('I', asan_ctor_statements, + MAX_RESERVED_INIT_PRIORITY - 1); } /* Initialize shadow_ptr_types array. */ diff --git a/gcc/asan.h b/gcc/asan.h index 6f0edbf..d9368a8 100644 --- a/gcc/asan.h +++ b/gcc/asan.h @@ -23,6 +23,7 @@ along with GCC; see the file COPYING3. If not see extern void asan_finish_file (void); extern rtx asan_emit_stack_protection (rtx, HOST_WIDE_INT *, tree *, int); +extern bool asan_protect_global (tree); /* Alias set for accessing the shadow memory. */ extern alias_set_type asan_shadow_set; @@ -56,4 +57,14 @@ asan_protect_stack_decl (tree decl) return DECL_P (decl) && !DECL_ARTIFICIAL (decl); } +/* Return the size of padding needed to insert after a protected + decl of SIZE. */ + +static inline unsigned int +asan_red_zone_size (unsigned int size) +{ + unsigned int c = size & (ASAN_RED_ZONE_SIZE - 1); + return c ? 2 * ASAN_RED_ZONE_SIZE - c : ASAN_RED_ZONE_SIZE; +} + #endif /* TREE_ASAN */ diff --git a/gcc/varasm.c b/gcc/varasm.c index b300348..641ce0c 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. */ -- 1.7.11.7 -- Dodji