diff options
Diffstat (limited to 'compiler-rt/lib/scudo/standalone/combined.h')
| -rw-r--r-- | compiler-rt/lib/scudo/standalone/combined.h | 88 | 
1 files changed, 71 insertions, 17 deletions
diff --git a/compiler-rt/lib/scudo/standalone/combined.h b/compiler-rt/lib/scudo/standalone/combined.h index 329ec45..ffe9554 100644 --- a/compiler-rt/lib/scudo/standalone/combined.h +++ b/compiler-rt/lib/scudo/standalone/combined.h @@ -706,19 +706,26 @@ public:          if (!getChunkFromBlock(Block, &Chunk, &Header) &&              !getChunkFromBlock(addHeaderTag(Block), &Chunk, &Header))            return; -      } else { -        if (!getChunkFromBlock(addHeaderTag(Block), &Chunk, &Header)) -          return; +      } else if (!getChunkFromBlock(addHeaderTag(Block), &Chunk, &Header)) { +        return;        } -      if (Header.State == Chunk::State::Allocated) { -        uptr TaggedChunk = Chunk; -        if (allocatorSupportsMemoryTagging<AllocatorConfig>()) -          TaggedChunk = untagPointer(TaggedChunk); -        if (useMemoryTagging<AllocatorConfig>(Primary.Options.load())) -          TaggedChunk = loadTag(Chunk); -        Callback(TaggedChunk, getSize(reinterpret_cast<void *>(Chunk), &Header), -                 Arg); + +      if (Header.State != Chunk::State::Allocated) +        return; + +      uptr TaggedChunk = Chunk; +      if (allocatorSupportsMemoryTagging<AllocatorConfig>()) +        TaggedChunk = untagPointer(TaggedChunk); +      uptr Size; +      if (UNLIKELY(useMemoryTagging<AllocatorConfig>(Primary.Options.load()))) { +        TaggedChunk = loadTag(Chunk); +        Size = getSize(reinterpret_cast<void *>(Chunk), &Header); +      } else if (AllocatorConfig::getExactUsableSize()) { +        Size = getSize(reinterpret_cast<void *>(Chunk), &Header); +      } else { +        Size = getUsableSize(reinterpret_cast<void *>(Chunk), &Header);        } +      Callback(TaggedChunk, Size, Arg);      };      Primary.iterateOverBlocks(Lambda);      Secondary.iterateOverBlocks(Lambda); @@ -759,16 +766,50 @@ public:      return false;    } -  // Return the usable size for a given chunk. Technically we lie, as we just -  // report the actual size of a chunk. This is done to counteract code actively -  // writing past the end of a chunk (like sqlite3) when the usable size allows -  // for it, which then forces realloc to copy the usable size of a chunk as -  // opposed to its actual size. +  ALWAYS_INLINE uptr getUsableSize(const void *Ptr, +                                   Chunk::UnpackedHeader *Header) { +    void *BlockBegin = getBlockBegin(Ptr, Header); +    if (LIKELY(Header->ClassId)) { +      return SizeClassMap::getSizeByClassId(Header->ClassId) - +             (reinterpret_cast<uptr>(Ptr) - reinterpret_cast<uptr>(BlockBegin)); +    } + +    uptr UntaggedPtr = reinterpret_cast<uptr>(Ptr); +    if (allocatorSupportsMemoryTagging<AllocatorConfig>()) { +      UntaggedPtr = untagPointer(UntaggedPtr); +      BlockBegin = untagPointer(BlockBegin); +    } +    return SecondaryT::getBlockEnd(BlockBegin) - UntaggedPtr; +  } + +  // Return the usable size for a given chunk. If MTE is enabled or if the +  // ExactUsableSize config parameter is true, we report the exact size of +  // the original allocation size. Otherwise, we will return the total +  // actual usable size.    uptr getUsableSize(const void *Ptr) {      if (UNLIKELY(!Ptr))        return 0; -    return getAllocSize(Ptr); +    if (AllocatorConfig::getExactUsableSize() || +        UNLIKELY(useMemoryTagging<AllocatorConfig>(Primary.Options.load()))) +      return getAllocSize(Ptr); + +    initThreadMaybe(); + +#ifdef GWP_ASAN_HOOKS +    if (UNLIKELY(GuardedAlloc.pointerIsMine(Ptr))) +      return GuardedAlloc.getSize(Ptr); +#endif // GWP_ASAN_HOOKS + +    Ptr = getHeaderTaggedPointer(const_cast<void *>(Ptr)); +    Chunk::UnpackedHeader Header; +    Chunk::loadHeader(Cookie, Ptr, &Header); + +    // Getting the alloc size of a chunk only makes sense if it's allocated. +    if (UNLIKELY(Header.State != Chunk::State::Allocated)) +      reportInvalidChunkState(AllocatorAction::Sizing, Ptr); + +    return getUsableSize(Ptr, &Header);    }    uptr getAllocSize(const void *Ptr) { @@ -951,6 +992,19 @@ public:                           MemorySize, 2, 16);    } +  uptr getBlockBeginTestOnly(const void *Ptr) { +    Chunk::UnpackedHeader Header; +    Chunk::loadHeader(Cookie, Ptr, &Header); +    DCHECK(Header.State == Chunk::State::Allocated); + +    if (allocatorSupportsMemoryTagging<AllocatorConfig>()) +      Ptr = untagPointer(const_cast<void *>(Ptr)); +    void *Begin = getBlockBegin(Ptr, &Header); +    if (allocatorSupportsMemoryTagging<AllocatorConfig>()) +      Begin = untagPointer(Begin); +    return reinterpret_cast<uptr>(Begin); +  } +  private:    typedef typename PrimaryT::SizeClassMap SizeClassMap;  | 
