Home | History | Annotate | Line # | Download | only in lsan
      1 //=-- lsan_allocator.h ----------------------------------------------------===//
      2 //
      3 //                     The LLVM Compiler Infrastructure
      4 //
      5 // This file is distributed under the University of Illinois Open Source
      6 // License. See LICENSE.TXT for details.
      7 //
      8 //===----------------------------------------------------------------------===//
      9 //
     10 // This file is a part of LeakSanitizer.
     11 // Allocator for standalone LSan.
     12 //
     13 //===----------------------------------------------------------------------===//
     14 
     15 #ifndef LSAN_ALLOCATOR_H
     16 #define LSAN_ALLOCATOR_H
     17 
     18 #include "sanitizer_common/sanitizer_allocator.h"
     19 #include "sanitizer_common/sanitizer_common.h"
     20 #include "sanitizer_common/sanitizer_internal_defs.h"
     21 #include "lsan_common.h"
     22 
     23 namespace __lsan {
     24 
     25 void *Allocate(const StackTrace &stack, uptr size, uptr alignment,
     26                bool cleared);
     27 void Deallocate(void *p);
     28 void *Reallocate(const StackTrace &stack, void *p, uptr new_size,
     29                  uptr alignment);
     30 uptr GetMallocUsableSize(const void *p);
     31 
     32 template<typename Callable>
     33 void ForEachChunk(const Callable &callback);
     34 
     35 void GetAllocatorCacheRange(uptr *begin, uptr *end);
     36 void AllocatorThreadFinish();
     37 void InitializeAllocator();
     38 
     39 const bool kAlwaysClearMemory = true;
     40 
     41 struct ChunkMetadata {
     42   u8 allocated : 8;  // Must be first.
     43   ChunkTag tag : 2;
     44 #if SANITIZER_WORDSIZE == 64
     45   uptr requested_size : 54;
     46 #else
     47   uptr requested_size : 32;
     48   uptr padding : 22;
     49 #endif
     50   u32 stack_trace_id;
     51 };
     52 
     53 #if defined(__mips64) || defined(__aarch64__) || defined(__i386__) || \
     54     defined(__arm__)
     55 static const uptr kRegionSizeLog = 20;
     56 static const uptr kNumRegions = SANITIZER_MMAP_RANGE_SIZE >> kRegionSizeLog;
     57 template <typename AddressSpaceView>
     58 using ByteMapASVT =
     59     TwoLevelByteMap<(kNumRegions >> 12), 1 << 12, AddressSpaceView>;
     60 
     61 template <typename AddressSpaceViewTy>
     62 struct AP32 {
     63   static const uptr kSpaceBeg = 0;
     64   static const u64 kSpaceSize = SANITIZER_MMAP_RANGE_SIZE;
     65   static const uptr kMetadataSize = sizeof(ChunkMetadata);
     66   typedef __sanitizer::CompactSizeClassMap SizeClassMap;
     67   static const uptr kRegionSizeLog = __lsan::kRegionSizeLog;
     68   using AddressSpaceView = AddressSpaceViewTy;
     69   using ByteMap = __lsan::ByteMapASVT<AddressSpaceView>;
     70   typedef NoOpMapUnmapCallback MapUnmapCallback;
     71   static const uptr kFlags = 0;
     72 };
     73 template <typename AddressSpaceView>
     74 using PrimaryAllocatorASVT = SizeClassAllocator32<AP32<AddressSpaceView>>;
     75 using PrimaryAllocator = PrimaryAllocatorASVT<LocalAddressSpaceView>;
     76 #elif defined(__x86_64__) || defined(__powerpc64__)
     77 # if defined(__powerpc64__)
     78 const uptr kAllocatorSpace = 0xa0000000000ULL;
     79 const uptr kAllocatorSize  = 0x20000000000ULL;  // 2T.
     80 # else
     81 const uptr kAllocatorSpace = 0x600000000000ULL;
     82 const uptr kAllocatorSize  = 0x40000000000ULL;  // 4T.
     83 # endif
     84 template <typename AddressSpaceViewTy>
     85 struct AP64 {  // Allocator64 parameters. Deliberately using a short name.
     86   static const uptr kSpaceBeg = kAllocatorSpace;
     87   static const uptr kSpaceSize = kAllocatorSize;
     88   static const uptr kMetadataSize = sizeof(ChunkMetadata);
     89   typedef DefaultSizeClassMap SizeClassMap;
     90   typedef NoOpMapUnmapCallback MapUnmapCallback;
     91   static const uptr kFlags = 0;
     92   using AddressSpaceView = AddressSpaceViewTy;
     93 };
     94 
     95 template <typename AddressSpaceView>
     96 using PrimaryAllocatorASVT = SizeClassAllocator64<AP64<AddressSpaceView>>;
     97 using PrimaryAllocator = PrimaryAllocatorASVT<LocalAddressSpaceView>;
     98 #endif
     99 
    100 template <typename AddressSpaceView>
    101 using AllocatorCacheASVT =
    102     SizeClassAllocatorLocalCache<PrimaryAllocatorASVT<AddressSpaceView>>;
    103 using AllocatorCache = AllocatorCacheASVT<LocalAddressSpaceView>;
    104 
    105 template <typename AddressSpaceView>
    106 using SecondaryAllocatorASVT =
    107     LargeMmapAllocator<NoOpMapUnmapCallback, DefaultLargeMmapAllocatorPtrArray,
    108                        AddressSpaceView>;
    109 
    110 template <typename AddressSpaceView>
    111 using AllocatorASVT =
    112     CombinedAllocator<PrimaryAllocatorASVT<AddressSpaceView>,
    113                       AllocatorCacheASVT<AddressSpaceView>,
    114                       SecondaryAllocatorASVT<AddressSpaceView>>;
    115 using Allocator = AllocatorASVT<LocalAddressSpaceView>;
    116 
    117 AllocatorCache *GetAllocatorCache();
    118 
    119 int lsan_posix_memalign(void **memptr, uptr alignment, uptr size,
    120                         const StackTrace &stack);
    121 void *lsan_aligned_alloc(uptr alignment, uptr size, const StackTrace &stack);
    122 void *lsan_memalign(uptr alignment, uptr size, const StackTrace &stack);
    123 void *lsan_malloc(uptr size, const StackTrace &stack);
    124 void lsan_free(void *p);
    125 void *lsan_realloc(void *p, uptr size, const StackTrace &stack);
    126 void *lsan_calloc(uptr nmemb, uptr size, const StackTrace &stack);
    127 void *lsan_valloc(uptr size, const StackTrace &stack);
    128 void *lsan_pvalloc(uptr size, const StackTrace &stack);
    129 uptr lsan_mz_size(const void *p);
    130 
    131 }  // namespace __lsan
    132 
    133 #endif  // LSAN_ALLOCATOR_H
    134