scudo_allocator.h 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  1. //===-- scudo_allocator.h ---------------------------------------*- C++ -*-===//
  2. //
  3. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  4. // See https://llvm.org/LICENSE.txt for license information.
  5. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  6. //
  7. //===----------------------------------------------------------------------===//
  8. ///
  9. /// Header for scudo_allocator.cpp.
  10. ///
  11. //===----------------------------------------------------------------------===//
  12. #ifndef SCUDO_ALLOCATOR_H_
  13. #define SCUDO_ALLOCATOR_H_
  14. #include "scudo_platform.h"
  15. namespace __scudo {
  16. enum AllocType : u8 {
  17. FromMalloc = 0, // Memory block came from malloc, realloc, calloc, etc.
  18. FromNew = 1, // Memory block came from operator new.
  19. FromNewArray = 2, // Memory block came from operator new [].
  20. FromMemalign = 3, // Memory block came from memalign, posix_memalign, etc.
  21. };
  22. enum ChunkState : u8 {
  23. ChunkAvailable = 0,
  24. ChunkAllocated = 1,
  25. ChunkQuarantine = 2
  26. };
  27. // Our header requires 64 bits of storage. Having the offset saves us from
  28. // using functions such as GetBlockBegin, that is fairly costly. Our first
  29. // implementation used the MetaData as well, which offers the advantage of
  30. // being stored away from the chunk itself, but accessing it was costly as
  31. // well. The header will be atomically loaded and stored.
  32. typedef u64 PackedHeader;
  33. struct UnpackedHeader {
  34. u64 Checksum : 16;
  35. u64 ClassId : 8;
  36. u64 SizeOrUnusedBytes : 20; // Size for Primary backed allocations, amount of
  37. // unused bytes in the chunk for Secondary ones.
  38. u64 State : 2; // available, allocated, or quarantined
  39. u64 AllocType : 2; // malloc, new, new[], or memalign
  40. u64 Offset : 16; // Offset from the beginning of the backend
  41. // allocation to the beginning of the chunk
  42. // itself, in multiples of MinAlignment. See
  43. // comment about its maximum value and in init().
  44. };
  45. typedef atomic_uint64_t AtomicPackedHeader;
  46. COMPILER_CHECK(sizeof(UnpackedHeader) == sizeof(PackedHeader));
  47. // Minimum alignment of 8 bytes for 32-bit, 16 for 64-bit
  48. const uptr MinAlignmentLog = FIRST_32_SECOND_64(3, 4);
  49. const uptr MaxAlignmentLog = 24; // 16 MB
  50. const uptr MinAlignment = 1 << MinAlignmentLog;
  51. const uptr MaxAlignment = 1 << MaxAlignmentLog;
  52. // constexpr version of __sanitizer::RoundUp without the extraneous CHECK.
  53. // This way we can use it in constexpr variables and functions declarations.
  54. constexpr uptr RoundUpTo(uptr Size, uptr Boundary) {
  55. return (Size + Boundary - 1) & ~(Boundary - 1);
  56. }
  57. namespace Chunk {
  58. constexpr uptr getHeaderSize() {
  59. return RoundUpTo(sizeof(PackedHeader), MinAlignment);
  60. }
  61. }
  62. #if SANITIZER_CAN_USE_ALLOCATOR64
  63. const uptr AllocatorSpace = ~0ULL;
  64. struct AP64 {
  65. static const uptr kSpaceBeg = AllocatorSpace;
  66. static const uptr kSpaceSize = AllocatorSize;
  67. static const uptr kMetadataSize = 0;
  68. typedef __scudo::SizeClassMap SizeClassMap;
  69. typedef NoOpMapUnmapCallback MapUnmapCallback;
  70. static const uptr kFlags =
  71. SizeClassAllocator64FlagMasks::kRandomShuffleChunks;
  72. using AddressSpaceView = LocalAddressSpaceView;
  73. };
  74. typedef SizeClassAllocator64<AP64> PrimaryT;
  75. #else
  76. struct AP32 {
  77. static const uptr kSpaceBeg = 0;
  78. static const u64 kSpaceSize = SANITIZER_MMAP_RANGE_SIZE;
  79. static const uptr kMetadataSize = 0;
  80. typedef __scudo::SizeClassMap SizeClassMap;
  81. static const uptr kRegionSizeLog = RegionSizeLog;
  82. using AddressSpaceView = LocalAddressSpaceView;
  83. typedef NoOpMapUnmapCallback MapUnmapCallback;
  84. static const uptr kFlags =
  85. SizeClassAllocator32FlagMasks::kRandomShuffleChunks |
  86. SizeClassAllocator32FlagMasks::kUseSeparateSizeClassForBatch;
  87. };
  88. typedef SizeClassAllocator32<AP32> PrimaryT;
  89. #endif // SANITIZER_CAN_USE_ALLOCATOR64
  90. #include "scudo_allocator_secondary.h"
  91. typedef LargeMmapAllocator SecondaryT;
  92. #include "scudo_allocator_combined.h"
  93. typedef CombinedAllocator BackendT;
  94. typedef CombinedAllocator::AllocatorCache AllocatorCacheT;
  95. void initScudo();
  96. void *scudoAllocate(uptr Size, uptr Alignment, AllocType Type);
  97. void scudoDeallocate(void *Ptr, uptr Size, uptr Alignment, AllocType Type);
  98. void *scudoRealloc(void *Ptr, uptr Size);
  99. void *scudoCalloc(uptr NMemB, uptr Size);
  100. void *scudoValloc(uptr Size);
  101. void *scudoPvalloc(uptr Size);
  102. int scudoPosixMemalign(void **MemPtr, uptr Alignment, uptr Size);
  103. void *scudoAlignedAlloc(uptr Alignment, uptr Size);
  104. uptr scudoMallocUsableSize(void *Ptr);
  105. } // namespace __scudo
  106. #endif // SCUDO_ALLOCATOR_H_