Patchwork [asan] Fix asan -fsection-anchors handling

login
register
mail settings
Submitter Jakub Jelinek
Date Dec. 21, 2012, 2:15 p.m.
Message ID <20121221141548.GH2315@tucnak.redhat.com>
Download mbox | patch
Permalink /patch/207826/
State New
Headers show

Comments

Jakub Jelinek - Dec. 21, 2012, 2:15 p.m.
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  <jakub@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.


	Jakub
Peter Bergner - Dec. 21, 2012, 6:10 p.m.
On Fri, 2012-12-21 at 15:15 +0100, Jakub Jelinek wrote:
> 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  <jakub@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.

FYI, this bootstrapped/regtested with no errors on powerpc64-linux and
fixes many of failures with the new asan test cases on powerpc*-linux.
Thanks Jakub!

Peter
Dodji Seketeli - Jan. 7, 2013, 5:13 p.m.
Jakub Jelinek <jakub@redhat.com> writes:

> 2012-12-21  Jakub Jelinek  <jakub@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.

This looks OK to me.  Thank you.

Patch

--- 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);