diff options
| -rw-r--r-- | compiler-rt/lib/asan/asan_allocator.cc | 40 | ||||
| -rw-r--r-- | compiler-rt/lib/sanitizer_common/sanitizer_common.h | 6 | 
2 files changed, 33 insertions, 13 deletions
| diff --git a/compiler-rt/lib/asan/asan_allocator.cc b/compiler-rt/lib/asan/asan_allocator.cc index 3a042d6f21a..16fb900e7ba 100644 --- a/compiler-rt/lib/asan/asan_allocator.cc +++ b/compiler-rt/lib/asan/asan_allocator.cc @@ -157,15 +157,26 @@ enum {  };  struct ChunkBase { +  // First 8 bytes.    uptr  chunk_state : 8;    uptr  size_class  : 8;    uptr  alloc_tid   : 24;    uptr  free_tid    : 24; -  u32  offset;  // User-visible memory starts at this+offset (beg()). -  uptr used_size;  // Size requested by the user. + +  // Second 8 bytes. +  uptr alignment_log : 8; +  uptr used_size : FIRST_32_SECOND_64(32, 56);  // Size requested by the user. + +  // The rest.    AsanChunk *next; -  uptr   beg() { return (uptr)this + offset; } +  // Typically the beginning of the user-accessible memory is 'this'+REDZONE +  // and is also aligned by REDZONE. However, if the memory is allocated +  // by memalign, the alignment might be higher and the user-accessible memory +  // starts at the first properly aligned address after the end of 'this'. +  uptr   Beg() { +    return RoundUpTo((uptr)this + sizeof(ChunkBase), 1 << alignment_log); +  }    uptr Size() { return SizeClassToSize(size_class); }    u8 SizeClass() { return size_class; }  }; @@ -189,27 +200,27 @@ struct AsanChunk: public ChunkBase {    }    bool AddrIsInside(uptr addr, uptr access_size, uptr *offset) { -    if (addr >= beg() && (addr + access_size) <= (beg() + used_size)) { -      *offset = addr - beg(); +    if (addr >= Beg() && (addr + access_size) <= (Beg() + used_size)) { +      *offset = addr - Beg();        return true;      }      return false;    }    bool AddrIsAtLeft(uptr addr, uptr access_size, uptr *offset) { -    if (addr < beg()) { -      *offset = beg() - addr; +    if (addr < Beg()) { +      *offset = Beg() - addr;        return true;      }      return false;    }    bool AddrIsAtRight(uptr addr, uptr access_size, uptr *offset) { -    if (addr + access_size >= beg() + used_size) { -      if (addr <= beg() + used_size) +    if (addr + access_size >= Beg() + used_size) { +      if (addr <= Beg() + used_size)          *offset = 0;        else -        *offset = addr - (beg() + used_size); +        *offset = addr - (Beg() + used_size);        return true;      }      return false; @@ -228,7 +239,7 @@ struct AsanChunk: public ChunkBase {        AsanPrintf(" somewhere around (this is AddressSanitizer bug!)");      }      AsanPrintf(" %zu-byte region [%p,%p)\n", -               used_size, (void*)beg(), (void*)(beg() + used_size)); +               used_size, (void*)Beg(), (void*)(Beg() + used_size));    }  }; @@ -676,11 +687,14 @@ static u8 *Allocate(uptr alignment, uptr size, AsanStackTrace *stack) {      AsanChunk *p = (AsanChunk*)(addr - REDZONE);      p->chunk_state = CHUNK_MEMALIGN;      p->next = m; +    m->alignment_log = Log2(alignment); +    CHECK(m->Beg() == addr); +  } else { +    m->alignment_log = Log2(REDZONE);    }    CHECK(m == PtrToChunk(addr));    m->used_size = size; -  m->offset = addr - (uptr)m; -  CHECK(m->beg() == addr); +  CHECK(m->Beg() == addr);    m->alloc_tid = t ? t->tid() : 0;    m->free_tid   = kInvalidTid;    AsanStackTrace::CompressStack(stack, m->compressed_alloc_stack(), diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_common.h b/compiler-rt/lib/sanitizer_common/sanitizer_common.h index f6025580494..566c3819653 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_common.h +++ b/compiler-rt/lib/sanitizer_common/sanitizer_common.h @@ -47,6 +47,12 @@ inline uptr RoundUpTo(uptr size, uptr boundary) {    return (size + boundary - 1) & ~(boundary - 1);  } +#if __WORDSIZE == 64 +# define FIRST_32_SECOND_64(a, b) (b) +#else +# define FIRST_32_SECOND_64(a, b) (a) +#endif +  }  // namespace __sanitizer  #endif  // SANITIZER_COMMON_H | 

