Hi! Peter reported on IRC that many asan tests are failing on ppc, apparently lots of that is related to -fsection-anchors decls and STRING_CSTs, which weren't considered before.
This patch attempts to fix all the issues I saw on the few testcases. Bootstrapped/regtested on x86_64-linux and i686-linux and eyeballed global-overflow-1.c and some other small testcase with a -> powerpc64-linux cross-compiler. Ok for trunk? 2012-12-21 Jakub Jelinek <ja...@redhat.com> * varasm.c (output_constant_def_contents): For asan_protect_global protected strings, adjust DECL_ALIGN if needed, before testing for anchored symbols. (place_block_symbol): Adjust size for asan protected STRING_CSTs if TREE_CONSTANT_POOL_ADDRESS_P. Increase alignment for asan protected normal decls. (output_object_block): For asan protected decls, emit asan padding after their contents. (asan_protect_global): Don't check TREE_ASM_WRITTEN here. (asan_finish_file): Test it here instead. --- gcc/varasm.c.jj 2012-12-20 19:10:19.856526720 +0100 +++ gcc/varasm.c 2012-12-21 10:37:44.481999545 +0100 @@ -3252,6 +3252,7 @@ output_constant_def_contents (rtx symbol tree decl = SYMBOL_REF_DECL (symbol); tree exp = DECL_INITIAL (decl); unsigned int align; + bool asan_protected = false; /* Make sure any other constants whose addresses appear in EXP are assigned label numbers. */ @@ -3260,6 +3261,14 @@ output_constant_def_contents (rtx symbol /* We are no longer deferring this constant. */ TREE_ASM_WRITTEN (decl) = TREE_ASM_WRITTEN (exp) = 1; + if (flag_asan && TREE_CODE (exp) == STRING_CST + && asan_protect_global (exp)) + { + asan_protected = true; + DECL_ALIGN (decl) = MAX (DECL_ALIGN (decl), + ASAN_RED_ZONE_SIZE * BITS_PER_UNIT); + } + /* If the constant is part of an object block, make sure that the decl has been positioned within its block, but do not write out its definition yet. output_object_blocks will do that later. */ @@ -3267,15 +3276,8 @@ 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); @@ -6968,6 +6970,10 @@ place_block_symbol (rtx symbol) decl = SYMBOL_REF_DECL (symbol); alignment = DECL_ALIGN (decl); size = get_constant_size (DECL_INITIAL (decl)); + if (flag_asan + && TREE_CODE (DECL_INITIAL (decl)) == STRING_CST + && asan_protect_global (DECL_INITIAL (decl))) + size += asan_red_zone_size (size); } else { @@ -6975,7 +6981,11 @@ place_block_symbol (rtx 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); + { + size += asan_red_zone_size (size); + alignment = MAX (alignment, + ASAN_RED_ZONE_SIZE * BITS_PER_UNIT); + } } /* Calculate the object's offset from the start of the block. */ @@ -7114,16 +7124,34 @@ output_object_block (struct object_block } else if (TREE_CONSTANT_POOL_ADDRESS_P (symbol)) { + HOST_WIDE_INT size; decl = SYMBOL_REF_DECL (symbol); assemble_constant_contents (DECL_INITIAL (decl), XSTR (symbol, 0), DECL_ALIGN (decl)); - offset += get_constant_size (DECL_INITIAL (decl)); + size = get_constant_size (DECL_INITIAL (decl)); + offset += size; + if (flag_asan + && TREE_CODE (DECL_INITIAL (decl)) == STRING_CST + && asan_protect_global (DECL_INITIAL (decl))) + { + size = asan_red_zone_size (size); + assemble_zeros (size); + offset += size; + } } else { + HOST_WIDE_INT size; decl = SYMBOL_REF_DECL (symbol); assemble_variable_contents (decl, XSTR (symbol, 0), false); - offset += tree_low_cst (DECL_SIZE_UNIT (decl), 1); + size = tree_low_cst (DECL_SIZE_UNIT (decl), 1); + offset += size; + if (flag_asan && asan_protect_global (decl)) + { + size = asan_red_zone_size (size); + assemble_zeros (size); + offset += size; + } } } } --- gcc/asan.c.jj 2012-12-20 11:38:14.000000000 +0100 +++ gcc/asan.c 2012-12-21 10:49:45.364823759 +0100 @@ -463,7 +463,6 @@ asan_protect_global (tree decl) || 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 @@ -1699,7 +1698,8 @@ asan_finish_file (void) tree fn = builtin_decl_implicit (BUILT_IN_ASAN_INIT); append_to_statement_list (build_call_expr (fn, 0), &asan_ctor_statements); FOR_EACH_DEFINED_VARIABLE (vnode) - if (asan_protect_global (vnode->symbol.decl)) + if (TREE_ASM_WRITTEN (vnode->symbol.decl) + && asan_protect_global (vnode->symbol.decl)) ++gcount; htab_t const_desc_htab = constant_pool_htab (); htab_traverse (const_desc_htab, count_string_csts, &gcount); @@ -1721,7 +1721,8 @@ asan_finish_file (void) DECL_IGNORED_P (var) = 1; vec_alloc (v, gcount); FOR_EACH_DEFINED_VARIABLE (vnode) - if (asan_protect_global (vnode->symbol.decl)) + if (TREE_ASM_WRITTEN (vnode->symbol.decl) + && asan_protect_global (vnode->symbol.decl)) asan_add_global (vnode->symbol.decl, TREE_TYPE (type), v); struct asan_add_string_csts_data aascd; aascd.type = TREE_TYPE (type); Jakub