Hi! On Sat, Dec 01, 2018 at 08:36:41AM +0100, Jakub Jelinek wrote: > I'm still seeing some regressions, ICEs like: > FAIL: c-c++-common/asan/clone-test-1.c -O1 (internal compiler error) > FAIL: c-c++-common/asan/clone-test-1.c -O1 (test for excess errors)
And here is a fix for that. It didn't trigger pretty much all the time just because the assert in asan_clear_shadow has been added to an uncommon spot, where clear_storage emits a libcall. The patch makes sure that the offset is aligned to ASAN_RED_ZONE_SIZE downward and size is padded up to make it a multiple of ASAN_RED_ZONE_SIZE too. E.g. on x86_64-linux we can emit rep; stosl instead of rep; stosb this way etc. Bootstrapped/regtested on x86_64-linux, i686-linux, powerpc64{,-le}-linux, committed to trunk to unbreak asan on powerpc64. 2018-12-02 Jakub Jelinek <ja...@redhat.com> PR sanitizer/88291 * asan.c (asan_clear_shadow): Move assert that len is multiple of 4 to the start of the function. (asan_emit_stack_protection): When emitting clearing sequence for epilogue, align offset down to ASAN_RED_ZONE_SIZE granularity, add last_size_aligned which is last_size padded to multiples of ASAN_RED_ZONE_SIZE and emit asan_clear_shadow always on 4 byte boundaries. * c-c++-common/asan/pr88291.c: New test. --- gcc/asan.c.jj 2018-12-01 08:31:30.000000000 +0100 +++ gcc/asan.c 2018-12-01 11:41:11.860166400 +0100 @@ -1165,6 +1165,7 @@ asan_clear_shadow (rtx shadow_mem, HOST_ rtx_code_label *top_label; rtx end, addr, tmp; + gcc_assert ((len & 3) == 0); start_sequence (); clear_storage (shadow_mem, GEN_INT (len), BLOCK_OP_NORMAL); insns = get_insns (); @@ -1178,7 +1179,6 @@ asan_clear_shadow (rtx shadow_mem, HOST_ return; } - gcc_assert ((len & 3) == 0); top_label = gen_label_rtx (); addr = copy_to_mode_reg (Pmode, XEXP (shadow_mem, 0)); shadow_mem = adjust_automodify_address (shadow_mem, SImode, addr, 0); @@ -1375,7 +1375,7 @@ asan_emit_stack_protection (rtx base, rt HOST_WIDE_INT base_offset = offsets[length - 1]; HOST_WIDE_INT base_align_bias = 0, offset, prev_offset; HOST_WIDE_INT asan_frame_size = offsets[0] - base_offset; - HOST_WIDE_INT last_offset, last_size; + HOST_WIDE_INT last_offset, last_size, last_size_aligned; int l; unsigned char cur_shadow_byte = ASAN_STACK_MAGIC_LEFT; tree str_cst, decl, id; @@ -1628,20 +1628,23 @@ asan_emit_stack_protection (rtx base, rt prev_offset = base_offset; last_offset = base_offset; last_size = 0; + last_size_aligned = 0; for (l = length; l; l -= 2) { offset = base_offset + ((offsets[l - 1] - base_offset) - & ~(ASAN_MIN_RED_ZONE_SIZE - HOST_WIDE_INT_1)); - if (last_offset + last_size != offset) + & ~(ASAN_RED_ZONE_SIZE - HOST_WIDE_INT_1)); + if (last_offset + last_size_aligned < offset) { shadow_mem = adjust_address (shadow_mem, VOIDmode, (last_offset - prev_offset) >> ASAN_SHADOW_SHIFT); prev_offset = last_offset; - asan_clear_shadow (shadow_mem, last_size >> ASAN_SHADOW_SHIFT); + asan_clear_shadow (shadow_mem, last_size_aligned >> ASAN_SHADOW_SHIFT); last_offset = offset; last_size = 0; } + else + last_size = offset - last_offset; last_size += base_offset + ((offsets[l - 2] - base_offset) & ~(ASAN_MIN_RED_ZONE_SIZE - HOST_WIDE_INT_1)) - offset; @@ -1667,13 +1670,16 @@ asan_emit_stack_protection (rtx base, rt last_size += size & ~(ASAN_MIN_RED_ZONE_SIZE - HOST_WIDE_INT_1); } } + last_size_aligned + = ((last_size + (ASAN_RED_ZONE_SIZE - HOST_WIDE_INT_1)) + & ~(ASAN_RED_ZONE_SIZE - HOST_WIDE_INT_1)); } - if (last_size) + if (last_size_aligned) { shadow_mem = adjust_address (shadow_mem, VOIDmode, (last_offset - prev_offset) >> ASAN_SHADOW_SHIFT); - asan_clear_shadow (shadow_mem, last_size >> ASAN_SHADOW_SHIFT); + asan_clear_shadow (shadow_mem, last_size_aligned >> ASAN_SHADOW_SHIFT); } /* Clean-up set with instrumented stack variables. */ --- gcc/testsuite/c-c++-common/asan/pr88291.c.jj 2018-12-01 11:34:42.448549265 +0100 +++ gcc/testsuite/c-c++-common/asan/pr88291.c 2018-12-01 11:29:49.561348917 +0100 @@ -0,0 +1,14 @@ +/* PR sanitizer/88291 */ +/* { dg-do compile } */ +/* { dg-options "-fsanitize=address -Os" } */ +/* { dg-additional-options "-mstringop-strategy=libcall" { target i?86-*-* x86_64-*-* } } */ + +void bar (void *, void *); + +void +foo (void) +{ + int b; + char __attribute__((aligned(16))) a[(1 << 20) + 1]; + bar (&a, &b); +} Jakub