123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125 |
- //===-- scudo_allocator.h ---------------------------------------*- C++ -*-===//
- //
- // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
- // See https://llvm.org/LICENSE.txt for license information.
- // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
- //
- //===----------------------------------------------------------------------===//
- ///
- /// Header for scudo_allocator.cpp.
- ///
- //===----------------------------------------------------------------------===//
- #ifndef SCUDO_ALLOCATOR_H_
- #define SCUDO_ALLOCATOR_H_
- #include "scudo_platform.h"
- namespace __scudo {
- enum AllocType : u8 {
- FromMalloc = 0, // Memory block came from malloc, realloc, calloc, etc.
- FromNew = 1, // Memory block came from operator new.
- FromNewArray = 2, // Memory block came from operator new [].
- FromMemalign = 3, // Memory block came from memalign, posix_memalign, etc.
- };
- enum ChunkState : u8 {
- ChunkAvailable = 0,
- ChunkAllocated = 1,
- ChunkQuarantine = 2
- };
- // Our header requires 64 bits of storage. Having the offset saves us from
- // using functions such as GetBlockBegin, that is fairly costly. Our first
- // implementation used the MetaData as well, which offers the advantage of
- // being stored away from the chunk itself, but accessing it was costly as
- // well. The header will be atomically loaded and stored.
- typedef u64 PackedHeader;
- struct UnpackedHeader {
- u64 Checksum : 16;
- u64 ClassId : 8;
- u64 SizeOrUnusedBytes : 20; // Size for Primary backed allocations, amount of
- // unused bytes in the chunk for Secondary ones.
- u64 State : 2; // available, allocated, or quarantined
- u64 AllocType : 2; // malloc, new, new[], or memalign
- u64 Offset : 16; // Offset from the beginning of the backend
- // allocation to the beginning of the chunk
- // itself, in multiples of MinAlignment. See
- // comment about its maximum value and in init().
- };
- typedef atomic_uint64_t AtomicPackedHeader;
- COMPILER_CHECK(sizeof(UnpackedHeader) == sizeof(PackedHeader));
- // Minimum alignment of 8 bytes for 32-bit, 16 for 64-bit
- const uptr MinAlignmentLog = FIRST_32_SECOND_64(3, 4);
- const uptr MaxAlignmentLog = 24; // 16 MB
- const uptr MinAlignment = 1 << MinAlignmentLog;
- const uptr MaxAlignment = 1 << MaxAlignmentLog;
- // constexpr version of __sanitizer::RoundUp without the extraneous CHECK.
- // This way we can use it in constexpr variables and functions declarations.
- constexpr uptr RoundUpTo(uptr Size, uptr Boundary) {
- return (Size + Boundary - 1) & ~(Boundary - 1);
- }
- namespace Chunk {
- constexpr uptr getHeaderSize() {
- return RoundUpTo(sizeof(PackedHeader), MinAlignment);
- }
- }
- #if SANITIZER_CAN_USE_ALLOCATOR64
- const uptr AllocatorSpace = ~0ULL;
- struct AP64 {
- static const uptr kSpaceBeg = AllocatorSpace;
- static const uptr kSpaceSize = AllocatorSize;
- static const uptr kMetadataSize = 0;
- typedef __scudo::SizeClassMap SizeClassMap;
- typedef NoOpMapUnmapCallback MapUnmapCallback;
- static const uptr kFlags =
- SizeClassAllocator64FlagMasks::kRandomShuffleChunks;
- using AddressSpaceView = LocalAddressSpaceView;
- };
- typedef SizeClassAllocator64<AP64> PrimaryT;
- #else
- struct AP32 {
- static const uptr kSpaceBeg = 0;
- static const u64 kSpaceSize = SANITIZER_MMAP_RANGE_SIZE;
- static const uptr kMetadataSize = 0;
- typedef __scudo::SizeClassMap SizeClassMap;
- static const uptr kRegionSizeLog = RegionSizeLog;
- using AddressSpaceView = LocalAddressSpaceView;
- typedef NoOpMapUnmapCallback MapUnmapCallback;
- static const uptr kFlags =
- SizeClassAllocator32FlagMasks::kRandomShuffleChunks |
- SizeClassAllocator32FlagMasks::kUseSeparateSizeClassForBatch;
- };
- typedef SizeClassAllocator32<AP32> PrimaryT;
- #endif // SANITIZER_CAN_USE_ALLOCATOR64
- #include "scudo_allocator_secondary.h"
- typedef LargeMmapAllocator SecondaryT;
- #include "scudo_allocator_combined.h"
- typedef CombinedAllocator BackendT;
- typedef CombinedAllocator::AllocatorCache AllocatorCacheT;
- void initScudo();
- void *scudoAllocate(uptr Size, uptr Alignment, AllocType Type);
- void scudoDeallocate(void *Ptr, uptr Size, uptr Alignment, AllocType Type);
- void *scudoRealloc(void *Ptr, uptr Size);
- void *scudoCalloc(uptr NMemB, uptr Size);
- void *scudoValloc(uptr Size);
- void *scudoPvalloc(uptr Size);
- int scudoPosixMemalign(void **MemPtr, uptr Alignment, uptr Size);
- void *scudoAlignedAlloc(uptr Alignment, uptr Size);
- uptr scudoMallocUsableSize(void *Ptr);
- } // namespace __scudo
- #endif // SCUDO_ALLOCATOR_H_
|