https://gcc.gnu.org/g:946c17e456d3a3c3d3baceffd245e7bbb580f7ed
commit r14-11253-g946c17e456d3a3c3d3baceffd245e7bbb580f7ed Author: Ilya Leoshkevich <i...@linux.ibm.com> Date: Wed Jan 8 00:17:07 2025 +0100 asan: Fix missing FakeStack flag cleanup 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. Link: https://inbox.sourceware.org/gcc-patches/20250109001702.154685-1-...@linux.ibm.com/ Signed-off-by: Ilya Leoshkevich <i...@linux.ibm.com> gcc/ChangeLog: * asan.cc (asan_emit_stack_protection): Always zero the flag unless it is cleared by the __asan_stack_free_N() libcall. (cherry picked from commit 13d971601175541146fda54682cde4d3f9cd2759) Diff: --- gcc/asan.cc | 37 ++++++++++++++++++------------------- 1 file changed, 18 insertions(+), 19 deletions(-) diff --git a/gcc/asan.cc b/gcc/asan.cc index 386aeec81557..268bb9fe0707 100644 --- a/gcc/asan.cc +++ b/gcc/asan.cc @@ -2100,28 +2100,13 @@ 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); - } + /* Emit memset (ShadowBase, kAsanStackAfterReturnMagic, ShadowSize). */ + store_by_pieces (shadow_mem, sz, builtin_memset_read_str, &c, + BITS_PER_UNIT, true, RETURN_BEGIN); else if (use_after_return_class >= 5 || !set_storage_via_setmem (shadow_mem, GEN_INT (sz), @@ -2138,6 +2123,20 @@ 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);