My port of addresssanitizer is based on GCC 4.8.1.
I modify "asan_emit_stack_protection" function in gcc/asan.c for the
following reason:
Sometimes, the stack variable size > 32 Bytes, and after asan
generates code to poison the shadow buffer,  it does clear some shadow
buffer but not all before function return.
So I use the way of poisoning to recover the shadow.
Does any of you suffer the problem? It works fine for my platform now.

about line 1050:
#if 0 // I find some false positive for those code
  for (l = length; l; l -= 2)
    {
      offset = base_offset + ((offsets[l - 1] - base_offset)
     & ~(ASAN_RED_ZONE_SIZE - HOST_WIDE_INT_1));
      if (last_offset + last_size != 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);
  last_offset = offset;
  last_size = 0;
}
      last_size += base_offset + ((offsets[l - 2] - base_offset)
  & ~(ASAN_RED_ZONE_SIZE - HOST_WIDE_INT_1))
   - offset;
    }
  if (last_size)
    {
      shadow_mem = adjust_address (shadow_mem, VOIDmode,
   (last_offset - prev_offset)
   >> ASAN_SHADOW_SHIFT);
      asan_clear_shadow (shadow_mem, last_size >> ASAN_SHADOW_SHIFT);
    }

 #else
  for (l = length; l; l -= 2)
  {
    if (l == 2)
      cur_shadow_byte = ASAN_STACK_MAGIC_RIGHT;
    offset = offsets[l - 1];
    if ((offset - base_offset) & (ASAN_RED_ZONE_SIZE - 1))
    {
      HOST_WIDE_INT aoff
        = base_offset + ((offset - base_offset)
                 & ~(ASAN_RED_ZONE_SIZE - HOST_WIDE_INT_1));
      shadow_mem = adjust_address (shadow_mem, VOIDmode,
                       (aoff - prev_offset)
                       >> ASAN_SHADOW_SHIFT);
      prev_offset = aoff;
      aoff += (1 << ASAN_SHADOW_SHIFT) << 2;

      asan_clear_shadow (shadow_mem, 4);
      offset = aoff;
    }
    while (offset <= offsets[l - 2] - ASAN_RED_ZONE_SIZE)
    {
      shadow_mem = adjust_address (shadow_mem, VOIDmode,
                       (offset - prev_offset)
                       >> ASAN_SHADOW_SHIFT);
      prev_offset = offset;

      asan_clear_shadow (shadow_mem, 4);
      offset += ASAN_RED_ZONE_SIZE;
    }
  }
  #endif

Reply via email to