132 lines
		
	
	
		
			4.9 KiB
		
	
	
	
		
			C++
		
	
	
	
			
		
		
	
	
			132 lines
		
	
	
		
			4.9 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;
 | 
						|
  using AddressSpaceView = LocalAddressSpaceView;
 | 
						|
};
 | 
						|
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;
 | 
						|
  using AddressSpaceView = LocalAddressSpaceView;
 | 
						|
  using ByteMap = __scudo::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_
 |