public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [asan] Never use memset for clearing of shadow mem in epilogues (PR fortran/55341)
@ 2012-12-19 12:10 Jakub Jelinek
  2013-01-08 16:31 ` Dodji Seketeli
  0 siblings, 1 reply; 2+ messages in thread
From: Jakub Jelinek @ 2012-12-19 12:10 UTC (permalink / raw)
  To: Konstantin Serebryany, Dmitry Vyukov, Dodji Seketeli; +Cc: gcc-patches

Hi!

clear_storage sometimes emits a library call instead of clearing storage by
pieces, rep stos* and similar, unfortunately if it is a call that libasan
intercepts (memset), it fails because it doesn't allow writes into shadow
mem.  Fixed by scanning the clear_storage sequence if there are any calls,
and if there are, replaces it with a simple loop storing 0.

Tested on x86_64-linux, ok for trunk?

2012-12-19  Jakub Jelinek  <jakub@redhat.com>

	PR fortran/55341
	* asan.c (asan_clear_shadow): New function.
	(asan_emit_stack_protection): Use it.

--- gcc/asan.c.jj	2012-12-13 00:05:04.000000000 +0100
+++ gcc/asan.c	2012-12-19 12:25:57.676365851 +0100
@@ -270,6 +270,45 @@ asan_shadow_cst (unsigned char shadow_by
   return GEN_INT (trunc_int_for_mode (val, SImode));
 }
 
+/* Clear shadow memory at SHADOW_MEM, LEN bytes.  Can't call a library call here
+   though.  */
+
+static void
+asan_clear_shadow (rtx shadow_mem, HOST_WIDE_INT len)
+{
+  rtx insn, insns, top_label, end, addr, tmp, jump;
+
+  start_sequence ();
+  clear_storage (shadow_mem, GEN_INT (len), BLOCK_OP_NORMAL);
+  insns = get_insns ();
+  end_sequence ();
+  for (insn = insns; insn; insn = NEXT_INSN (insn))
+    if (CALL_P (insn))
+      break;
+  if (insn == NULL_RTX)
+    {
+      emit_insn (insns);
+      return;
+    }
+
+  gcc_assert ((len & 3) == 0);
+  top_label = gen_label_rtx ();
+  addr = force_reg (Pmode, XEXP (shadow_mem, 0));
+  shadow_mem = adjust_automodify_address (shadow_mem, SImode, addr, 0);
+  end = force_reg (Pmode, plus_constant (Pmode, addr, len));
+  emit_label (top_label);
+
+  emit_move_insn (shadow_mem, const0_rtx);
+  tmp = expand_simple_binop (Pmode, PLUS, addr, GEN_INT (4), addr,
+                             true, OPTAB_LIB_WIDEN);
+  if (tmp != addr)
+    emit_move_insn (addr, tmp);
+  emit_cmp_and_jump_insns (addr, end, LT, NULL_RTX, Pmode, true, top_label);
+  jump = get_last_insn ();
+  gcc_assert (JUMP_P (jump));
+  add_reg_note (jump, REG_BR_PROB, GEN_INT (REG_BR_PROB_BASE * 80 / 100));
+}
+
 /* Insert code to protect stack vars.  The prologue sequence should be emitted
    directly, epilogue sequence returned.  BASE is the register holding the
    stack base, against which OFFSETS array offsets are relative to, OFFSETS
@@ -404,8 +443,7 @@ asan_emit_stack_protection (rtx base, HO
 				       (last_offset - prev_offset)
 				       >> ASAN_SHADOW_SHIFT);
 	  prev_offset = last_offset;
-	  clear_storage (shadow_mem, GEN_INT (last_size >> ASAN_SHADOW_SHIFT),
-			 BLOCK_OP_NORMAL);
+	  asan_clear_shadow (shadow_mem, last_size >> ASAN_SHADOW_SHIFT);
 	  last_offset = offset;
 	  last_size = 0;
 	}
@@ -418,8 +456,7 @@ asan_emit_stack_protection (rtx base, HO
       shadow_mem = adjust_address (shadow_mem, VOIDmode,
 				   (last_offset - prev_offset)
 				   >> ASAN_SHADOW_SHIFT);
-      clear_storage (shadow_mem, GEN_INT (last_size >> ASAN_SHADOW_SHIFT),
-		     BLOCK_OP_NORMAL);
+      asan_clear_shadow (shadow_mem, last_size >> ASAN_SHADOW_SHIFT);
     }
 
   do_pending_stack_adjust ();

	Jakub

^ permalink raw reply	[flat|nested] 2+ messages in thread

* Re: [asan] Never use memset for clearing of shadow mem in epilogues (PR fortran/55341)
  2012-12-19 12:10 [asan] Never use memset for clearing of shadow mem in epilogues (PR fortran/55341) Jakub Jelinek
@ 2013-01-08 16:31 ` Dodji Seketeli
  0 siblings, 0 replies; 2+ messages in thread
From: Dodji Seketeli @ 2013-01-08 16:31 UTC (permalink / raw)
  To: Jakub Jelinek; +Cc: Konstantin Serebryany, Dmitry Vyukov, gcc-patches

Jakub Jelinek <jakub@redhat.com> writes:

> 2012-12-19  Jakub Jelinek  <jakub@redhat.com>
>
> 	PR fortran/55341
> 	* asan.c (asan_clear_shadow): New function.
> 	(asan_emit_stack_protection): Use it.

This looks OK to me.  Thanks.

-- 
		Dodji

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2013-01-08 16:31 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-12-19 12:10 [asan] Never use memset for clearing of shadow mem in epilogues (PR fortran/55341) Jakub Jelinek
2013-01-08 16:31 ` Dodji Seketeli

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).