Jakub Jelinek <[email protected]> writes:
> On Wed, Oct 16, 2013 at 09:35:21AM +0400, Yury Gribov wrote:
>> >>> I've recently submitted a bug report regarding invalid
>> unpoisoning of stack frame redzones
>> (http://gcc.gnu.org/bugzilla/show_bug.cgi?id=58543). Could someone
>> take a look at proposed patch (a simple one-liner) and check whether
>> it's ok for commit?
>> >>
>> >> Can you please be more verbose
>> >
>> > Do you think the proposed patch is ok or should I provide some
>> additional info?
>>
>> Jakub, Dodji,
>>
>> Any updates on this one? Note that this bug is a huge blocker for
>> using AddressSanitizer on ARM platforms.
>
> Sorry for the delay, I finally found time to look at it.
> While your patch fixes the issue, I wonder if for the case where
> shadow_mem before the asan_clear_shadow call is already of the form
> (mem (reg)) it isn't better to just adjust next asan_clear_shadow
> base from the end of the cleared region rather than from the start of it,
> because the end will be already in the right pseudo, while with your
> approach it needs to be done in a different register and potentially
> increase register pressure. So here is (completely untested) alternate fix:
Hmm, it just seems wrong to be assigning to registers returned by force_reg
and expand_binop though. Would this variation be OK?
Thanks,
Richard
Index: gcc/asan.c
===================================================================
--- gcc/asan.c (revision 204124)
+++ gcc/asan.c (working copy)
@@ -876,9 +876,10 @@
}
/* Clear shadow memory at SHADOW_MEM, LEN bytes. Can't call a library call
here
- though. */
+ though. If the address of the next byte is in a known register, return
+ that register, otherwise return null. */
-static void
+static rtx
asan_clear_shadow (rtx shadow_mem, HOST_WIDE_INT len)
{
rtx insn, insns, top_label, end, addr, tmp, jump;
@@ -893,12 +894,12 @@
if (insn == NULL_RTX)
{
emit_insn (insns);
- return;
+ return 0;
}
gcc_assert ((len & 3) == 0);
top_label = gen_label_rtx ();
- addr = force_reg (Pmode, XEXP (shadow_mem, 0));
+ addr = copy_to_mode_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);
@@ -912,6 +913,7 @@
jump = get_last_insn ();
gcc_assert (JUMP_P (jump));
add_int_reg_note (jump, REG_BR_PROB, REG_BR_PROB_BASE * 80 / 100);
+ return addr;
}
/* Insert code to protect stack vars. The prologue sequence should be emitted
@@ -1048,7 +1050,15 @@
(last_offset - prev_offset)
>> ASAN_SHADOW_SHIFT);
prev_offset = last_offset;
- asan_clear_shadow (shadow_mem, last_size >> ASAN_SHADOW_SHIFT);
+ rtx end_addr = asan_clear_shadow (shadow_mem,
+ last_size >> ASAN_SHADOW_SHIFT);
+ if (end_addr)
+ {
+ shadow_mem
+ = adjust_automodify_address (shadow_mem, VOIDmode, end_addr,
+ last_size >> ASAN_SHADOW_SHIFT);
+ prev_offset += last_size;
+ }
last_offset = offset;
last_size = 0;
}