asan_allocator.h revision 276851
1251881Speter//===-- asan_allocator.h ----------------------------------------*- C++ -*-===// 2251881Speter// 3251881Speter// The LLVM Compiler Infrastructure 4251881Speter// 5251881Speter// This file is distributed under the University of Illinois Open Source 6251881Speter// License. See LICENSE.TXT for details. 7251881Speter// 8251881Speter//===----------------------------------------------------------------------===// 9251881Speter// 10251881Speter// This file is a part of AddressSanitizer, an address sanity checker. 11251881Speter// 12251881Speter// ASan-private header for asan_allocator2.cc. 13251881Speter//===----------------------------------------------------------------------===// 14251881Speter 15251881Speter#ifndef ASAN_ALLOCATOR_H 16251881Speter#define ASAN_ALLOCATOR_H 17251881Speter 18251881Speter#include "asan_internal.h" 19251881Speter#include "asan_interceptors.h" 20251881Speter#include "sanitizer_common/sanitizer_allocator.h" 21251881Speter#include "sanitizer_common/sanitizer_list.h" 22251881Speter 23251881Speternamespace __asan { 24251881Speter 25251881Speterenum AllocType { 26251881Speter FROM_MALLOC = 1, // Memory block came from malloc, calloc, realloc, etc. 27251881Speter FROM_NEW = 2, // Memory block came from operator new. 28251881Speter FROM_NEW_BR = 3 // Memory block came from operator new [ ] 29251881Speter}; 30251881Speter 31251881Speterstatic const uptr kNumberOfSizeClasses = 255; 32251881Speterstruct AsanChunk; 33251881Speter 34251881Spetervoid InitializeAllocator(); 35251881Spetervoid ReInitializeAllocator(); 36251881Speter 37251881Speterclass AsanChunkView { 38251881Speter public: 39251881Speter explicit AsanChunkView(AsanChunk *chunk) : chunk_(chunk) {} 40251881Speter bool IsValid(); // Checks if AsanChunkView points to a valid allocated 41251881Speter // or quarantined chunk. 42251881Speter uptr Beg(); // First byte of user memory. 43251881Speter uptr End(); // Last byte of user memory. 44251881Speter uptr UsedSize(); // Size requested by the user. 45251881Speter uptr AllocTid(); 46251881Speter uptr FreeTid(); 47251881Speter bool Eq(const AsanChunkView &c) const { return chunk_ == c.chunk_; } 48251881Speter StackTrace GetAllocStack(); 49251881Speter StackTrace GetFreeStack(); 50251881Speter bool AddrIsInside(uptr addr, uptr access_size, sptr *offset) { 51251881Speter if (addr >= Beg() && (addr + access_size) <= End()) { 52251881Speter *offset = addr - Beg(); 53251881Speter return true; 54251881Speter } 55251881Speter return false; 56251881Speter } 57251881Speter bool AddrIsAtLeft(uptr addr, uptr access_size, sptr *offset) { 58251881Speter (void)access_size; 59251881Speter if (addr < Beg()) { 60251881Speter *offset = Beg() - addr; 61251881Speter return true; 62251881Speter } 63251881Speter return false; 64251881Speter } 65251881Speter bool AddrIsAtRight(uptr addr, uptr access_size, sptr *offset) { 66251881Speter if (addr + access_size > End()) { 67251881Speter *offset = addr - End(); 68251881Speter return true; 69251881Speter } 70251881Speter return false; 71251881Speter } 72251881Speter 73251881Speter private: 74251881Speter AsanChunk *const chunk_; 75251881Speter}; 76251881Speter 77251881SpeterAsanChunkView FindHeapChunkByAddress(uptr address); 78251881Speter 79251881Speter// List of AsanChunks with total size. 80251881Speterclass AsanChunkFifoList: public IntrusiveList<AsanChunk> { 81251881Speter public: 82251881Speter explicit AsanChunkFifoList(LinkerInitialized) { } 83251881Speter AsanChunkFifoList() { clear(); } 84251881Speter void Push(AsanChunk *n); 85251881Speter void PushList(AsanChunkFifoList *q); 86251881Speter AsanChunk *Pop(); 87251881Speter uptr size() { return size_; } 88251881Speter void clear() { 89251881Speter IntrusiveList<AsanChunk>::clear(); 90251881Speter size_ = 0; 91251881Speter } 92251881Speter private: 93251881Speter uptr size_; 94251881Speter}; 95251881Speter 96251881Speterstruct AsanMapUnmapCallback { 97251881Speter void OnMap(uptr p, uptr size) const; 98251881Speter void OnUnmap(uptr p, uptr size) const; 99299742Sdim}; 100251881Speter 101251881Speter#if SANITIZER_CAN_USE_ALLOCATOR64 102251881Speter# if defined(__powerpc64__) 103251881Speterconst uptr kAllocatorSpace = 0xa0000000000ULL; 104251881Speterconst uptr kAllocatorSize = 0x20000000000ULL; // 2T. 105251881Speter# else 106251881Speterconst uptr kAllocatorSpace = 0x600000000000ULL; 107251881Speterconst uptr kAllocatorSize = 0x40000000000ULL; // 4T. 108299742Sdim# endif 109251881Spetertypedef DefaultSizeClassMap SizeClassMap; 110251881Spetertypedef SizeClassAllocator64<kAllocatorSpace, kAllocatorSize, 0 /*metadata*/, 111251881Speter SizeClassMap, AsanMapUnmapCallback> PrimaryAllocator; 112251881Speter#else // Fallback to SizeClassAllocator32. 113251881Speterstatic const uptr kRegionSizeLog = 20; 114251881Speterstatic const uptr kNumRegions = SANITIZER_MMAP_RANGE_SIZE >> kRegionSizeLog; 115299742Sdim# if SANITIZER_WORDSIZE == 32 116299742Sdimtypedef FlatByteMap<kNumRegions> ByteMap; 117299742Sdim# elif SANITIZER_WORDSIZE == 64 118299742Sdimtypedef TwoLevelByteMap<(kNumRegions >> 12), 1 << 12> ByteMap; 119299742Sdim# endif 120299742Sdimtypedef CompactSizeClassMap SizeClassMap; 121299742Sdimtypedef SizeClassAllocator32<0, SANITIZER_MMAP_RANGE_SIZE, 16, 122299742Sdim SizeClassMap, kRegionSizeLog, 123299742Sdim ByteMap, 124299742Sdim AsanMapUnmapCallback> PrimaryAllocator; 125299742Sdim#endif // SANITIZER_CAN_USE_ALLOCATOR64 126299742Sdim 127299742Sdimtypedef SizeClassAllocatorLocalCache<PrimaryAllocator> AllocatorCache; 128299742Sdimtypedef LargeMmapAllocator<AsanMapUnmapCallback> SecondaryAllocator; 129299742Sdimtypedef CombinedAllocator<PrimaryAllocator, AllocatorCache, 130299742Sdim SecondaryAllocator> Allocator; 131251881Speter 132299742Sdim 133299742Sdimstruct AsanThreadLocalMallocStorage { 134299742Sdim uptr quarantine_cache[16]; 135299742Sdim AllocatorCache allocator2_cache; 136299742Sdim void CommitBack(); 137299742Sdim private: 138299742Sdim // These objects are allocated via mmap() and are zero-initialized. 139299742Sdim AsanThreadLocalMallocStorage() {} 140299742Sdim}; 141299742Sdim 142299742Sdimvoid *asan_memalign(uptr alignment, uptr size, BufferedStackTrace *stack, 143299742Sdim AllocType alloc_type); 144299742Sdimvoid asan_free(void *ptr, BufferedStackTrace *stack, AllocType alloc_type); 145299742Sdimvoid asan_sized_free(void *ptr, uptr size, BufferedStackTrace *stack, 146299742Sdim AllocType alloc_type); 147299742Sdim 148299742Sdimvoid *asan_malloc(uptr size, BufferedStackTrace *stack); 149299742Sdimvoid *asan_calloc(uptr nmemb, uptr size, BufferedStackTrace *stack); 150299742Sdimvoid *asan_realloc(void *p, uptr size, BufferedStackTrace *stack); 151299742Sdimvoid *asan_valloc(uptr size, BufferedStackTrace *stack); 152251881Spetervoid *asan_pvalloc(uptr size, BufferedStackTrace *stack); 153251881Speter 154251881Speterint asan_posix_memalign(void **memptr, uptr alignment, uptr size, 155251881Speter BufferedStackTrace *stack); 156251881Speteruptr asan_malloc_usable_size(void *ptr, uptr pc, uptr bp); 157251881Speter 158251881Speteruptr asan_mz_size(const void *ptr); 159251881Spetervoid asan_mz_force_lock(); 160299742Sdimvoid asan_mz_force_unlock(); 161299742Sdim 162299742Sdimvoid PrintInternalAllocatorStats(); 163299742Sdim 164299742Sdim} // namespace __asan 165251881Speter#endif // ASAN_ALLOCATOR_H 166251881Speter