(root)/
gcc-13.2.0/
libsanitizer/
hwasan/
hwasan_allocator.h
       1  //===-- hwasan_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  // This file is a part of HWAddressSanitizer.
      10  //
      11  //===----------------------------------------------------------------------===//
      12  
      13  #ifndef HWASAN_ALLOCATOR_H
      14  #define HWASAN_ALLOCATOR_H
      15  
      16  #include "hwasan.h"
      17  #include "hwasan_interface_internal.h"
      18  #include "hwasan_mapping.h"
      19  #include "hwasan_poisoning.h"
      20  #include "sanitizer_common/sanitizer_allocator.h"
      21  #include "sanitizer_common/sanitizer_allocator_checks.h"
      22  #include "sanitizer_common/sanitizer_allocator_interface.h"
      23  #include "sanitizer_common/sanitizer_allocator_report.h"
      24  #include "sanitizer_common/sanitizer_common.h"
      25  #include "sanitizer_common/sanitizer_ring_buffer.h"
      26  
      27  #if !defined(__aarch64__) && !defined(__x86_64__) && !(SANITIZER_RISCV64)
      28  #  error Unsupported platform
      29  #endif
      30  
      31  namespace __hwasan {
      32  
      33  struct Metadata {
      34    u32 requested_size_low;
      35    u32 requested_size_high : 31;
      36    u32 right_aligned : 1;
      37    u32 alloc_context_id;
      38    u64 get_requested_size() {
      39      return (static_cast<u64>(requested_size_high) << 32) + requested_size_low;
      40    }
      41    void set_requested_size(u64 size) {
      42      requested_size_low = size & ((1ul << 32) - 1);
      43      requested_size_high = size >> 32;
      44    }
      45  };
      46  
      47  struct HwasanMapUnmapCallback {
      48    void OnMap(uptr p, uptr size) const { UpdateMemoryUsage(); }
      49    void OnUnmap(uptr p, uptr size) const {
      50      // We are about to unmap a chunk of user memory.
      51      // It can return as user-requested mmap() or another thread stack.
      52      // Make it accessible with zero-tagged pointer.
      53      TagMemory(p, size, 0);
      54    }
      55  };
      56  
      57  static const uptr kMaxAllowedMallocSize = 1UL << 40;  // 1T
      58  
      59  struct AP64 {
      60    static const uptr kSpaceBeg = ~0ULL;
      61  
      62  #if defined(HWASAN_ALIASING_MODE)
      63    static const uptr kSpaceSize = 1ULL << kAddressTagShift;
      64  #else
      65    static const uptr kSpaceSize = 0x2000000000ULL;
      66  #endif
      67    static const uptr kMetadataSize = sizeof(Metadata);
      68    typedef __sanitizer::VeryDenseSizeClassMap SizeClassMap;
      69    using AddressSpaceView = LocalAddressSpaceView;
      70    typedef HwasanMapUnmapCallback MapUnmapCallback;
      71    static const uptr kFlags = 0;
      72  };
      73  typedef SizeClassAllocator64<AP64> PrimaryAllocator;
      74  typedef CombinedAllocator<PrimaryAllocator> Allocator;
      75  typedef Allocator::AllocatorCache AllocatorCache;
      76  
      77  void AllocatorSwallowThreadLocalCache(AllocatorCache *cache);
      78  
      79  class HwasanChunkView {
      80   public:
      81    HwasanChunkView() : block_(0), metadata_(nullptr) {}
      82    HwasanChunkView(uptr block, Metadata *metadata)
      83        : block_(block), metadata_(metadata) {}
      84    bool IsAllocated() const;    // Checks if the memory is currently allocated
      85    uptr Beg() const;            // First byte of user memory
      86    uptr End() const;            // Last byte of user memory
      87    uptr UsedSize() const;       // Size requested by the user
      88    uptr ActualSize() const;     // Size allocated by the allocator.
      89    u32 GetAllocStackId() const;
      90    bool FromSmallHeap() const;
      91   private:
      92    uptr block_;
      93    Metadata *const metadata_;
      94  };
      95  
      96  HwasanChunkView FindHeapChunkByAddress(uptr address);
      97  
      98  // Information about one (de)allocation that happened in the past.
      99  // These are recorded in a thread-local ring buffer.
     100  // TODO: this is currently 24 bytes (20 bytes + alignment).
     101  // Compress it to 16 bytes or extend it to be more useful.
     102  struct HeapAllocationRecord {
     103    uptr tagged_addr;
     104    u32  alloc_context_id;
     105    u32  free_context_id;
     106    u32  requested_size;
     107  };
     108  
     109  typedef RingBuffer<HeapAllocationRecord> HeapAllocationsRingBuffer;
     110  
     111  void GetAllocatorStats(AllocatorStatCounters s);
     112  
     113  inline bool InTaggableRegion(uptr addr) {
     114  #if defined(HWASAN_ALIASING_MODE)
     115    // Aliases are mapped next to shadow so that the upper bits match the shadow
     116    // base.
     117    return (addr >> kTaggableRegionCheckShift) ==
     118           (GetShadowOffset() >> kTaggableRegionCheckShift);
     119  #endif
     120    return true;
     121  }
     122  
     123  } // namespace __hwasan
     124  
     125  #endif // HWASAN_ALLOCATOR_H