Bootstrapped and regtested on x86_64-redhat-linux. Ok for master?
The FakeStack flag is not zeroed out when can_store_by_pieces() returns false. Over time, this causes FakeStack::Allocate() to perform the maximum number of loop iterations, significantly slowing down the instrumented program. gcc/ChangeLog: * asan.cc (asan_emit_stack_protection): Always zero the flag unless it is cleared by the __asan_stack_free_N() libcall. Signed-off-by: Ilya Leoshkevich <i...@linux.ibm.com> --- gcc/asan.cc | 30 ++++++++++++++++++------------ 1 file changed, 18 insertions(+), 12 deletions(-) diff --git a/gcc/asan.cc b/gcc/asan.cc index 452a5a33327..da21d5e1008 100644 --- a/gcc/asan.cc +++ b/gcc/asan.cc @@ -2167,27 +2167,16 @@ asan_emit_stack_protection (rtx base, rtx pbase, unsigned int alignb, mem = adjust_address (mem, VOIDmode, base_align_bias); emit_move_insn (mem, gen_int_mode (ASAN_STACK_RETIRED_MAGIC, ptr_mode)); unsigned HOST_WIDE_INT sz = asan_frame_size >> ASAN_SHADOW_SHIFT; + bool asan_stack_free_emitted_p = false; if (use_after_return_class < 5 && can_store_by_pieces (sz, builtin_memset_read_str, &c, BITS_PER_UNIT, true)) { /* Emit: memset(ShadowBase, kAsanStackAfterReturnMagic, ShadowSize); - **SavedFlagPtr(FakeStack, class_id) = 0 */ store_by_pieces (shadow_mem, sz, builtin_memset_read_str, &c, BITS_PER_UNIT, true, RETURN_BEGIN); - - unsigned HOST_WIDE_INT offset - = (1 << (use_after_return_class + 6)); - offset -= GET_MODE_SIZE (ptr_mode); - mem = gen_rtx_MEM (ptr_mode, base); - mem = adjust_address (mem, ptr_mode, offset); - rtx addr = gen_reg_rtx (ptr_mode); - emit_move_insn (addr, mem); - addr = convert_memory_address (Pmode, addr); - mem = gen_rtx_MEM (QImode, addr); - emit_move_insn (mem, const0_rtx); } else if (use_after_return_class >= 5 || !set_storage_via_setmem (shadow_mem, @@ -2205,6 +2194,23 @@ asan_emit_stack_protection (rtx base, rtx pbase, unsigned int alignb, GEN_INT (asan_frame_size + base_align_bias), TYPE_MODE (pointer_sized_int_node), orig_addr, ptr_mode); + asan_stack_free_emitted_p = true; + } + if (!asan_stack_free_emitted_p) + { + /* Emit: + **SavedFlagPtr (FakeStack, class_id) = 0 + */ + unsigned HOST_WIDE_INT offset + = (1 << (use_after_return_class + 6)); + offset -= GET_MODE_SIZE (ptr_mode); + mem = gen_rtx_MEM (ptr_mode, base); + mem = adjust_address (mem, ptr_mode, offset); + rtx addr = gen_reg_rtx (ptr_mode); + emit_move_insn (addr, mem); + addr = convert_memory_address (Pmode, addr); + mem = gen_rtx_MEM (QImode, addr); + emit_move_insn (mem, const0_rtx); } lab = gen_label_rtx (); emit_jump (lab); -- 2.47.1