annotate compiler-rt/lib/gwp_asan/guarded_pool_allocator.h @ 266:00f31e85ec16 default tip

Added tag current for changeset 31d058e83c98
author Shinji KONO <kono@ie.u-ryukyu.ac.jp>
date Sat, 14 Oct 2023 10:13:55 +0900
parents 1f2b6ac9f198
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
150
anatofuz
parents:
diff changeset
1 //===-- guarded_pool_allocator.h --------------------------------*- C++ -*-===//
anatofuz
parents:
diff changeset
2 //
anatofuz
parents:
diff changeset
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
anatofuz
parents:
diff changeset
4 // See https://llvm.org/LICENSE.txt for license information.
anatofuz
parents:
diff changeset
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
anatofuz
parents:
diff changeset
6 //
anatofuz
parents:
diff changeset
7 //===----------------------------------------------------------------------===//
anatofuz
parents:
diff changeset
8
anatofuz
parents:
diff changeset
9 #ifndef GWP_ASAN_GUARDED_POOL_ALLOCATOR_H_
anatofuz
parents:
diff changeset
10 #define GWP_ASAN_GUARDED_POOL_ALLOCATOR_H_
anatofuz
parents:
diff changeset
11
anatofuz
parents:
diff changeset
12 #include "gwp_asan/common.h"
anatofuz
parents:
diff changeset
13 #include "gwp_asan/definitions.h"
anatofuz
parents:
diff changeset
14 #include "gwp_asan/mutex.h"
anatofuz
parents:
diff changeset
15 #include "gwp_asan/options.h"
221
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
16 #include "gwp_asan/platform_specific/guarded_pool_allocator_fuchsia.h" // IWYU pragma: keep
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
17 #include "gwp_asan/platform_specific/guarded_pool_allocator_posix.h" // IWYU pragma: keep
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
18 #include "gwp_asan/platform_specific/guarded_pool_allocator_tls.h"
150
anatofuz
parents:
diff changeset
19
anatofuz
parents:
diff changeset
20 #include <stddef.h>
anatofuz
parents:
diff changeset
21 #include <stdint.h>
221
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
22 // IWYU pragma: no_include <__stddef_max_align_t.h>
150
anatofuz
parents:
diff changeset
23
anatofuz
parents:
diff changeset
24 namespace gwp_asan {
anatofuz
parents:
diff changeset
25 // This class is the primary implementation of the allocator portion of GWP-
anatofuz
parents:
diff changeset
26 // ASan. It is the sole owner of the pool of sequentially allocated guarded
anatofuz
parents:
diff changeset
27 // slots. It should always be treated as a singleton.
anatofuz
parents:
diff changeset
28
anatofuz
parents:
diff changeset
29 // Functions in the public interface of this class are thread-compatible until
anatofuz
parents:
diff changeset
30 // init() is called, at which point they become thread-safe (unless specified
anatofuz
parents:
diff changeset
31 // otherwise).
anatofuz
parents:
diff changeset
32 class GuardedPoolAllocator {
anatofuz
parents:
diff changeset
33 public:
anatofuz
parents:
diff changeset
34 // Name of the GWP-ASan mapping that for `Metadata`.
anatofuz
parents:
diff changeset
35 static constexpr const char *kGwpAsanMetadataName = "GWP-ASan Metadata";
anatofuz
parents:
diff changeset
36
anatofuz
parents:
diff changeset
37 // During program startup, we must ensure that memory allocations do not land
anatofuz
parents:
diff changeset
38 // in this allocation pool if the allocator decides to runtime-disable
anatofuz
parents:
diff changeset
39 // GWP-ASan. The constructor value-initialises the class such that if no
anatofuz
parents:
diff changeset
40 // further initialisation takes place, calls to shouldSample() and
anatofuz
parents:
diff changeset
41 // pointerIsMine() will return false.
221
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
42 constexpr GuardedPoolAllocator() {}
150
anatofuz
parents:
diff changeset
43 GuardedPoolAllocator(const GuardedPoolAllocator &) = delete;
anatofuz
parents:
diff changeset
44 GuardedPoolAllocator &operator=(const GuardedPoolAllocator &) = delete;
anatofuz
parents:
diff changeset
45
anatofuz
parents:
diff changeset
46 // Note: This class is expected to be a singleton for the lifetime of the
anatofuz
parents:
diff changeset
47 // program. If this object is initialised, it will leak the guarded page pool
anatofuz
parents:
diff changeset
48 // and metadata allocations during destruction. We can't clean up these areas
anatofuz
parents:
diff changeset
49 // as this may cause a use-after-free on shutdown.
anatofuz
parents:
diff changeset
50 ~GuardedPoolAllocator() = default;
anatofuz
parents:
diff changeset
51
anatofuz
parents:
diff changeset
52 // Initialise the rest of the members of this class. Create the allocation
anatofuz
parents:
diff changeset
53 // pool using the provided options. See options.inc for runtime configuration
anatofuz
parents:
diff changeset
54 // options.
anatofuz
parents:
diff changeset
55 void init(const options::Options &Opts);
anatofuz
parents:
diff changeset
56 void uninitTestOnly();
anatofuz
parents:
diff changeset
57
anatofuz
parents:
diff changeset
58 // Functions exported for libmemunreachable's use on Android. disable()
anatofuz
parents:
diff changeset
59 // installs a lock in the allocator that prevents any thread from being able
anatofuz
parents:
diff changeset
60 // to allocate memory, until enable() is called.
anatofuz
parents:
diff changeset
61 void disable();
anatofuz
parents:
diff changeset
62 void enable();
anatofuz
parents:
diff changeset
63
anatofuz
parents:
diff changeset
64 typedef void (*iterate_callback)(uintptr_t base, size_t size, void *arg);
anatofuz
parents:
diff changeset
65 // Execute the callback Cb for every allocation the lies in [Base, Base +
anatofuz
parents:
diff changeset
66 // Size). Must be called while the allocator is disabled. The callback can not
anatofuz
parents:
diff changeset
67 // allocate.
anatofuz
parents:
diff changeset
68 void iterate(void *Base, size_t Size, iterate_callback Cb, void *Arg);
anatofuz
parents:
diff changeset
69
anatofuz
parents:
diff changeset
70 // Return whether the allocation should be randomly chosen for sampling.
anatofuz
parents:
diff changeset
71 GWP_ASAN_ALWAYS_INLINE bool shouldSample() {
anatofuz
parents:
diff changeset
72 // NextSampleCounter == 0 means we "should regenerate the counter".
anatofuz
parents:
diff changeset
73 // == 1 means we "should sample this allocation".
anatofuz
parents:
diff changeset
74 // AdjustedSampleRatePlusOne is designed to intentionally underflow. This
anatofuz
parents:
diff changeset
75 // class must be valid when zero-initialised, and we wish to sample as
anatofuz
parents:
diff changeset
76 // infrequently as possible when this is the case, hence we underflow to
anatofuz
parents:
diff changeset
77 // UINT32_MAX.
221
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
78 if (GWP_ASAN_UNLIKELY(getThreadLocals()->NextSampleCounter == 0))
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
79 getThreadLocals()->NextSampleCounter =
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
80 ((getRandomUnsigned32() % (AdjustedSampleRatePlusOne - 1)) + 1) &
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
81 ThreadLocalPackedVariables::NextSampleCounterMask;
150
anatofuz
parents:
diff changeset
82
221
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
83 return GWP_ASAN_UNLIKELY(--getThreadLocals()->NextSampleCounter == 0);
150
anatofuz
parents:
diff changeset
84 }
anatofuz
parents:
diff changeset
85
anatofuz
parents:
diff changeset
86 // Returns whether the provided pointer is a current sampled allocation that
anatofuz
parents:
diff changeset
87 // is owned by this pool.
anatofuz
parents:
diff changeset
88 GWP_ASAN_ALWAYS_INLINE bool pointerIsMine(const void *Ptr) const {
anatofuz
parents:
diff changeset
89 return State.pointerIsMine(Ptr);
anatofuz
parents:
diff changeset
90 }
anatofuz
parents:
diff changeset
91
221
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
92 // Allocate memory in a guarded slot, with the specified `Alignment`. Returns
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
93 // nullptr if the pool is empty, if the alignnment is not a power of two, or
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
94 // if the size/alignment makes the allocation too large for this pool to
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
95 // handle. By default, uses strong alignment (i.e. `max_align_t`), see
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
96 // http://www.open-std.org/jtc1/sc22/wg14/www/docs/n2293.htm for discussion of
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
97 // alignment issues in the standard.
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
98 void *allocate(size_t Size, size_t Alignment = alignof(max_align_t));
150
anatofuz
parents:
diff changeset
99
anatofuz
parents:
diff changeset
100 // Deallocate memory in a guarded slot. The provided pointer must have been
anatofuz
parents:
diff changeset
101 // allocated using this pool. This will set the guarded slot as inaccessible.
anatofuz
parents:
diff changeset
102 void deallocate(void *Ptr);
anatofuz
parents:
diff changeset
103
anatofuz
parents:
diff changeset
104 // Returns the size of the allocation at Ptr.
anatofuz
parents:
diff changeset
105 size_t getSize(const void *Ptr);
anatofuz
parents:
diff changeset
106
anatofuz
parents:
diff changeset
107 // Returns a pointer to the Metadata region, or nullptr if it doesn't exist.
anatofuz
parents:
diff changeset
108 const AllocationMetadata *getMetadataRegion() const { return Metadata; }
anatofuz
parents:
diff changeset
109
anatofuz
parents:
diff changeset
110 // Returns a pointer to the AllocatorState region.
anatofuz
parents:
diff changeset
111 const AllocatorState *getAllocatorState() const { return &State; }
anatofuz
parents:
diff changeset
112
252
1f2b6ac9f198 LLVM16-1
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 221
diff changeset
113 // Functions that the signal handler is responsible for calling, while
1f2b6ac9f198 LLVM16-1
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 221
diff changeset
114 // providing the SEGV pointer, prior to dumping the crash, and after dumping
1f2b6ac9f198 LLVM16-1
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 221
diff changeset
115 // the crash (in recoverable mode only).
1f2b6ac9f198 LLVM16-1
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 221
diff changeset
116 void preCrashReport(void *Ptr);
1f2b6ac9f198 LLVM16-1
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 221
diff changeset
117 void postCrashReportRecoverableOnly(void *Ptr);
1f2b6ac9f198 LLVM16-1
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 221
diff changeset
118
221
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
119 // Exposed as protected for testing.
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
120 protected:
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
121 // Returns the actual allocation size required to service an allocation with
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
122 // the provided Size and Alignment.
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
123 static size_t getRequiredBackingSize(size_t Size, size_t Alignment,
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
124 size_t PageSize);
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
125
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
126 // Returns the provided pointer that meets the specified alignment, depending
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
127 // on whether it's left or right aligned.
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
128 static uintptr_t alignUp(uintptr_t Ptr, size_t Alignment);
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
129 static uintptr_t alignDown(uintptr_t Ptr, size_t Alignment);
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
130
150
anatofuz
parents:
diff changeset
131 private:
anatofuz
parents:
diff changeset
132 // Name of actively-occupied slot mappings.
anatofuz
parents:
diff changeset
133 static constexpr const char *kGwpAsanAliveSlotName = "GWP-ASan Alive Slot";
anatofuz
parents:
diff changeset
134 // Name of the guard pages. This includes all slots that are not actively in
anatofuz
parents:
diff changeset
135 // use (i.e. were never used, or have been free()'d).)
anatofuz
parents:
diff changeset
136 static constexpr const char *kGwpAsanGuardPageName = "GWP-ASan Guard Page";
anatofuz
parents:
diff changeset
137 // Name of the mapping for `FreeSlots`.
anatofuz
parents:
diff changeset
138 static constexpr const char *kGwpAsanFreeSlotsName = "GWP-ASan Metadata";
anatofuz
parents:
diff changeset
139
anatofuz
parents:
diff changeset
140 static constexpr size_t kInvalidSlotID = SIZE_MAX;
anatofuz
parents:
diff changeset
141
anatofuz
parents:
diff changeset
142 // These functions anonymously map memory or change the permissions of mapped
anatofuz
parents:
diff changeset
143 // memory into this process in a platform-specific way. Pointer and size
anatofuz
parents:
diff changeset
144 // arguments are expected to be page-aligned. These functions will never
anatofuz
parents:
diff changeset
145 // return on error, instead electing to kill the calling process on failure.
221
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
146 // The pool memory is initially reserved and inaccessible, and RW mappings are
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
147 // subsequently created and destroyed via allocateInGuardedPool() and
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
148 // deallocateInGuardedPool(). Each mapping is named on platforms that support
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
149 // it, primarily Android. This name must be a statically allocated string, as
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
150 // the Android kernel uses the string pointer directly.
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
151 void *map(size_t Size, const char *Name) const;
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
152 void unmap(void *Ptr, size_t Size) const;
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
153
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
154 // The pool is managed separately, as some platforms (particularly Fuchsia)
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
155 // manage virtual memory regions as a chunk where individual pages can still
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
156 // have separate permissions. These platforms maintain metadata about the
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
157 // region in order to perform operations. The pool is unique as it's the only
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
158 // thing in GWP-ASan that treats pages in a single VM region on an individual
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
159 // basis for page protection.
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
160 // The pointer returned by reserveGuardedPool() is the reserved address range
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
161 // of (at least) Size bytes.
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
162 void *reserveGuardedPool(size_t Size);
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
163 // allocateInGuardedPool() Ptr and Size must be a subrange of the previously
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
164 // reserved pool range.
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
165 void allocateInGuardedPool(void *Ptr, size_t Size) const;
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
166 // deallocateInGuardedPool() Ptr and Size must be an exact pair previously
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
167 // passed to allocateInGuardedPool().
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
168 void deallocateInGuardedPool(void *Ptr, size_t Size) const;
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
169 void unreserveGuardedPool();
150
anatofuz
parents:
diff changeset
170
anatofuz
parents:
diff changeset
171 // Get the page size from the platform-specific implementation. Only needs to
anatofuz
parents:
diff changeset
172 // be called once, and the result should be cached in PageSize in this class.
anatofuz
parents:
diff changeset
173 static size_t getPlatformPageSize();
anatofuz
parents:
diff changeset
174
anatofuz
parents:
diff changeset
175 // Returns a pointer to the metadata for the owned pointer. If the pointer is
anatofuz
parents:
diff changeset
176 // not owned by this pool, the result is undefined.
anatofuz
parents:
diff changeset
177 AllocationMetadata *addrToMetadata(uintptr_t Ptr) const;
anatofuz
parents:
diff changeset
178
anatofuz
parents:
diff changeset
179 // Reserve a slot for a new guarded allocation. Returns kInvalidSlotID if no
anatofuz
parents:
diff changeset
180 // slot is available to be reserved.
anatofuz
parents:
diff changeset
181 size_t reserveSlot();
anatofuz
parents:
diff changeset
182
anatofuz
parents:
diff changeset
183 // Unreserve the guarded slot.
anatofuz
parents:
diff changeset
184 void freeSlot(size_t SlotIndex);
anatofuz
parents:
diff changeset
185
anatofuz
parents:
diff changeset
186 // Raise a SEGV and set the corresponding fields in the Allocator's State in
anatofuz
parents:
diff changeset
187 // order to tell the crash handler what happened. Used when errors are
anatofuz
parents:
diff changeset
188 // detected internally (Double Free, Invalid Free).
252
1f2b6ac9f198 LLVM16-1
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 221
diff changeset
189 void raiseInternallyDetectedError(uintptr_t Address, Error E);
150
anatofuz
parents:
diff changeset
190
anatofuz
parents:
diff changeset
191 static GuardedPoolAllocator *getSingleton();
anatofuz
parents:
diff changeset
192
anatofuz
parents:
diff changeset
193 // Install a pthread_atfork handler.
anatofuz
parents:
diff changeset
194 void installAtFork();
anatofuz
parents:
diff changeset
195
anatofuz
parents:
diff changeset
196 gwp_asan::AllocatorState State;
anatofuz
parents:
diff changeset
197
anatofuz
parents:
diff changeset
198 // A mutex to protect the guarded slot and metadata pool for this class.
anatofuz
parents:
diff changeset
199 Mutex PoolMutex;
221
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
200 // Some unwinders can grab the libdl lock. In order to provide atfork
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
201 // protection, we need to ensure that we allow an unwinding thread to release
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
202 // the libdl lock before forking.
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
203 Mutex BacktraceMutex;
150
anatofuz
parents:
diff changeset
204 // Record the number allocations that we've sampled. We store this amount so
anatofuz
parents:
diff changeset
205 // that we don't randomly choose to recycle a slot that previously had an
anatofuz
parents:
diff changeset
206 // allocation before all the slots have been utilised.
anatofuz
parents:
diff changeset
207 size_t NumSampledAllocations = 0;
anatofuz
parents:
diff changeset
208 // Pointer to the allocation metadata (allocation/deallocation stack traces),
anatofuz
parents:
diff changeset
209 // if any.
anatofuz
parents:
diff changeset
210 AllocationMetadata *Metadata = nullptr;
anatofuz
parents:
diff changeset
211
anatofuz
parents:
diff changeset
212 // Pointer to an array of free slot indexes.
anatofuz
parents:
diff changeset
213 size_t *FreeSlots = nullptr;
anatofuz
parents:
diff changeset
214 // The current length of the list of free slots.
anatofuz
parents:
diff changeset
215 size_t FreeSlotsLength = 0;
anatofuz
parents:
diff changeset
216
anatofuz
parents:
diff changeset
217 // See options.{h, inc} for more information.
anatofuz
parents:
diff changeset
218 bool PerfectlyRightAlign = false;
anatofuz
parents:
diff changeset
219
anatofuz
parents:
diff changeset
220 // Backtrace function provided by the supporting allocator. See `options.h`
anatofuz
parents:
diff changeset
221 // for more information.
anatofuz
parents:
diff changeset
222 options::Backtrace_t Backtrace = nullptr;
anatofuz
parents:
diff changeset
223
anatofuz
parents:
diff changeset
224 // The adjusted sample rate for allocation sampling. Default *must* be
anatofuz
parents:
diff changeset
225 // nonzero, as dynamic initialisation may call malloc (e.g. from libstdc++)
anatofuz
parents:
diff changeset
226 // before GPA::init() is called. This would cause an error in shouldSample(),
anatofuz
parents:
diff changeset
227 // where we would calculate modulo zero. This value is set UINT32_MAX, as when
anatofuz
parents:
diff changeset
228 // GWP-ASan is disabled, we wish to never spend wasted cycles recalculating
anatofuz
parents:
diff changeset
229 // the sample rate.
anatofuz
parents:
diff changeset
230 uint32_t AdjustedSampleRatePlusOne = 0;
anatofuz
parents:
diff changeset
231
221
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
232 // Additional platform specific data structure for the guarded pool mapping.
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
233 PlatformSpecificMapData GuardedPagePoolPlatformData = {};
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
234
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
235 class ScopedRecursiveGuard {
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
236 public:
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
237 ScopedRecursiveGuard() { getThreadLocals()->RecursiveGuard = true; }
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
238 ~ScopedRecursiveGuard() { getThreadLocals()->RecursiveGuard = false; }
150
anatofuz
parents:
diff changeset
239 };
221
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
240
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
241 // Initialise the PRNG, platform-specific.
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
242 void initPRNG();
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
243
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
244 // xorshift (32-bit output), extremely fast PRNG that uses arithmetic
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
245 // operations only. Seeded using platform-specific mechanisms by initPRNG().
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
246 uint32_t getRandomUnsigned32();
150
anatofuz
parents:
diff changeset
247 };
anatofuz
parents:
diff changeset
248 } // namespace gwp_asan
anatofuz
parents:
diff changeset
249
anatofuz
parents:
diff changeset
250 #endif // GWP_ASAN_GUARDED_POOL_ALLOCATOR_H_