1 //===-- hwasan_allocator.h --------------------------------------*- C++ -*-===//
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
7 //===----------------------------------------------------------------------===//
9 // This file is a part of HWAddressSanitizer.
11 //===----------------------------------------------------------------------===//
13 #ifndef HWASAN_ALLOCATOR_H
14 #define HWASAN_ALLOCATOR_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__)
28 #error Unsupported platform
34 u32 requested_size_low
;
35 u32 requested_size_high
: 31;
36 u32 right_aligned
: 1;
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
60 static const uptr kSpaceBeg
= ~0ULL;
62 #if defined(HWASAN_ALIASING_MODE)
63 static const uptr kSpaceSize
= 1ULL << kAddressTagShift
;
65 static const uptr kSpaceSize
= 0x2000000000ULL
;
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
{
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;
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
{
104 u32 alloc_context_id
;
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
117 return (addr
>> kTaggableRegionCheckShift
) ==
118 (GetShadowOffset() >> kTaggableRegionCheckShift
);
123 } // namespace __hwasan
125 #endif // HWASAN_ALLOCATOR_H