libstdc++: Adding missing feature-test macros for C++23 ranges algos
[official-gcc.git] / libsanitizer / hwasan / hwasan_allocator.h
blobbae53b565592a2ed1ca1d4aa6184bd8dfdb39c93
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.
11 //===----------------------------------------------------------------------===//
13 #ifndef HWASAN_ALLOCATOR_H
14 #define HWASAN_ALLOCATOR_H
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"
27 #if !defined(__aarch64__) && !defined(__x86_64__) && !(SANITIZER_RISCV64)
28 # error Unsupported platform
29 #endif
31 namespace __hwasan {
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;
41 void set_requested_size(u64 size) {
42 requested_size_low = size & ((1ul << 32) - 1);
43 requested_size_high = size >> 32;
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);
57 static const uptr kMaxAllowedMallocSize = 1UL << 40; // 1T
59 struct AP64 {
60 static const uptr kSpaceBeg = ~0ULL;
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;
73 typedef SizeClassAllocator64<AP64> PrimaryAllocator;
74 typedef CombinedAllocator<PrimaryAllocator> Allocator;
75 typedef Allocator::AllocatorCache AllocatorCache;
77 void AllocatorSwallowThreadLocalCache(AllocatorCache *cache);
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_;
96 HwasanChunkView FindHeapChunkByAddress(uptr address);
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;
109 typedef RingBuffer<HeapAllocationRecord> HeapAllocationsRingBuffer;
111 void GetAllocatorStats(AllocatorStatCounters s);
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;
123 } // namespace __hwasan
125 #endif // HWASAN_ALLOCATOR_H