
Summary: There is currently too much redundancy in the class/variable/* names in Scudo: - we are in the namespace `__scudo`, so there is no point in having something named `ScudoX` to end up with a final name of `__scudo::ScudoX`; - there are a lot of types/* that have `Allocator` in the name, given that Scudo is an allocator I figure this doubles up as well. So change a bunch of the Scudo names to make them shorter, less redundant, and overall simpler. They should still be pretty self explaining (or at least it looks so to me). The TSD part will be done in another CL (eg `__scudo::ScudoTSD`). Reviewers: alekseyshl, eugenis Reviewed By: alekseyshl Subscribers: delcypher, #sanitizers, llvm-commits Differential Revision: https://reviews.llvm.org/D49505 llvm-svn: 337557
130 lines
4.8 KiB
C++
130 lines
4.8 KiB
C++
//===-- scudo_allocator.h ---------------------------------------*- C++ -*-===//
|
|
//
|
|
// The LLVM Compiler Infrastructure
|
|
//
|
|
// This file is distributed under the University of Illinois Open Source
|
|
// License. See LICENSE.TXT for details.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
///
|
|
/// 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;
|
|
};
|
|
typedef SizeClassAllocator64<AP64> PrimaryT;
|
|
#else
|
|
static const uptr NumRegions = SANITIZER_MMAP_RANGE_SIZE >> RegionSizeLog;
|
|
# if SANITIZER_WORDSIZE == 32
|
|
typedef FlatByteMap<NumRegions> ByteMap;
|
|
# elif SANITIZER_WORDSIZE == 64
|
|
typedef TwoLevelByteMap<(NumRegions >> 12), 1 << 12> ByteMap;
|
|
# endif // SANITIZER_WORDSIZE
|
|
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;
|
|
typedef __scudo::ByteMap ByteMap;
|
|
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"
|
|
#include "scudo_allocator_combined.h"
|
|
|
|
typedef SizeClassAllocatorLocalCache<PrimaryT> AllocatorCacheT;
|
|
typedef LargeMmapAllocator SecondaryT;
|
|
typedef CombinedAllocator<PrimaryT, AllocatorCacheT, SecondaryT> BackendT;
|
|
|
|
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_
|