diff options
Diffstat (limited to 'gcc/varasm.c')
-rw-r--r-- | gcc/varasm.c | 19 |
1 files changed, 17 insertions, 2 deletions
diff --git a/gcc/varasm.c b/gcc/varasm.c index ee42afc..3c420c0 100644 --- a/gcc/varasm.c +++ b/gcc/varasm.c @@ -3249,11 +3249,23 @@ output_constant_def_contents (rtx symbol) place_block_symbol (symbol); else { + bool asan_protected = false; align = DECL_ALIGN (decl); switch_to_section (get_constant_section (exp, align)); + if (flag_asan && TREE_CODE (exp) == STRING_CST + && asan_protect_global (exp)) + { + asan_protected = true; + align = MAX (align, ASAN_RED_ZONE_SIZE * BITS_PER_UNIT); + } if (align > BITS_PER_UNIT) ASM_OUTPUT_ALIGN (asm_out_file, floor_log2 (align / BITS_PER_UNIT)); assemble_constant_contents (exp, XSTR (symbol, 0), align); + if (asan_protected) + { + HOST_WIDE_INT size = get_constant_size (exp); + assemble_zeros (asan_red_zone_size (size)); + } } if (flag_mudflap) mudflap_enqueue_constant (exp); @@ -6157,7 +6169,9 @@ categorize_decl_for_section (const_tree decl, int reloc) return SECCAT_TEXT; else if (TREE_CODE (decl) == STRING_CST) { - if (flag_mudflap) /* or !flag_merge_constants */ + if (flag_mudflap + || (flag_asan && asan_protect_global (CONST_CAST_TREE (decl)))) + /* or !flag_merge_constants */ return SECCAT_RODATA; else return SECCAT_RODATA_MERGE_STR; @@ -6181,7 +6195,8 @@ categorize_decl_for_section (const_tree decl, int reloc) } else if (reloc & targetm.asm_out.reloc_rw_mask ()) ret = reloc == 1 ? SECCAT_DATA_REL_RO_LOCAL : SECCAT_DATA_REL_RO; - else if (reloc || flag_merge_constants < 2) + else if (reloc || flag_merge_constants < 2 || flag_mudflap + || (flag_asan && asan_protect_global (CONST_CAST_TREE (decl)))) /* C and C++ don't allow different variables to share the same location. -fmerge-all-constants allows even that (at the expense of not conforming). */ |