On Thu, Jan 09, 2025 at 01:15:30AM +0100, Ilya Leoshkevich wrote:
> 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.
Took me a while to construct a testcase where it makes a difference, but e.g.
void foo (int *, int *, int *, int *, int *, int *);
int
bar (void)
{
int a[3], b[26];
foo (a, b, 0, 0, 0, 0);
return 0;
}
int
baz (void)
{
int a[3], b[26], c[371], d[12], e[257], f[5];
foo (a, b, c, d, e, f);
return 0;
}
shows it on s390x with -O2 -fsanitize=address on bar but not baz (on x86_64
not on either).
> 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 <[email protected]>
> ---
> 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);
> }
This if body becomes single statement, so the {}s around it should be
dropped
and the comment and store_by_pieces call reindented by 2 columns to the
left.
> @@ -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);
Ok for trunk with that nit fixed.
Jakub