diff options
author | Kostya Kortchinsky <kostyak@google.com> | 2016-12-13 19:31:54 +0000 |
---|---|---|
committer | Kostya Kortchinsky <kostyak@google.com> | 2016-12-13 19:31:54 +0000 |
commit | 5b8087e9a144cb8a8bef13714978422bd1b08892 (patch) | |
tree | 7cf2e3ebd5470da16fd0c949efae0d8bf0ea46fa /lib/scudo/scudo_allocator.cpp | |
parent | 06f626a00f7c60c010593c856b13d69a5e8adae3 (diff) |
Corrected D27428: Do not use the alignment-rounded-up size with secondary
Summary:
I atually had an integer overflow on 32-bit with D27428 that didn't reproduce
locally, as the test servers would manage allocate addresses in the 0xffffxxxx
range, which led to some issues when rounding addresses.
At this point, I feel that Scudo could benefit from having its own combined
allocator, as we don't get any benefit from the current one, but have to work
around some hurdles (alignment checks, rounding up that is no longer needed,
extraneous code).
Reviewers: kcc, alekseyshl
Subscribers: llvm-commits, kubabrecka
Differential Revision: https://reviews.llvm.org/D27681
git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@289572 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/scudo/scudo_allocator.cpp')
-rw-r--r-- | lib/scudo/scudo_allocator.cpp | 15 |
1 files changed, 12 insertions, 3 deletions
diff --git a/lib/scudo/scudo_allocator.cpp b/lib/scudo/scudo_allocator.cpp index 57a2be494..4f3b05ffb 100644 --- a/lib/scudo/scudo_allocator.cpp +++ b/lib/scudo/scudo_allocator.cpp @@ -402,12 +402,18 @@ struct Allocator { Size = 1; if (Size >= MaxAllowedMallocSize) return BackendAllocator.ReturnNullOrDieOnBadRequest(); - uptr RoundedSize = RoundUpTo(Size, MinAlignment); - uptr NeededSize = RoundedSize + AlignedChunkHeaderSize; + + uptr NeededSize = RoundUpTo(Size, MinAlignment) + AlignedChunkHeaderSize; if (Alignment > MinAlignment) NeededSize += Alignment; if (NeededSize >= MaxAllowedMallocSize) return BackendAllocator.ReturnNullOrDieOnBadRequest(); + + // Primary backed and Secondary backed allocations have a different + // treatment. We deal with alignment requirements of Primary serviced + // allocations here, but the Secondary will take care of its own alignment + // needs, which means we also have to work around some limitations of the + // combined allocator to accommodate the situation. bool FromPrimary = PrimaryAllocator::CanAllocate(NeededSize, MinAlignment); void *Ptr; @@ -426,8 +432,11 @@ struct Allocator { // If the allocation was serviced by the secondary, the returned pointer // accounts for ChunkHeaderSize to pass the alignment check of the combined // allocator. Adjust it here. - if (!FromPrimary) + if (!FromPrimary) { AllocBeg -= AlignedChunkHeaderSize; + if (Alignment > MinAlignment) + NeededSize -= Alignment; + } uptr ActuallyAllocatedSize = BackendAllocator.GetActuallyAllocatedSize( reinterpret_cast<void *>(AllocBeg)); |