blob: dc5f606688f9c9326527cf60d274eb71d209c81d [file] [log] [blame]
Jakub Staszak0c4468b2012-11-14 20:18:34 +00001//===- llvm/unittest/Support/AllocatorTest.cpp - BumpPtrAllocator tests ---===//
2//
Chandler Carruth2946cd72019-01-19 08:50:56 +00003// 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
Jakub Staszak0c4468b2012-11-14 20:18:34 +00006//
7//===----------------------------------------------------------------------===//
8
9#include "llvm/Support/Memory.h"
10#include "llvm/Support/Process.h"
Jakub Staszak0c4468b2012-11-14 20:18:34 +000011#include "gtest/gtest.h"
Michal Gorny1b25ba02018-11-20 18:38:11 +000012#include <cassert>
Jakub Staszak0c4468b2012-11-14 20:18:34 +000013#include <cstdlib>
14
Michal Gorny1b25ba02018-11-20 18:38:11 +000015#if defined(__NetBSD__)
16// clang-format off
17#include <sys/param.h>
18#include <sys/types.h>
19#include <sys/sysctl.h>
20#include <err.h>
21#include <unistd.h>
22// clang-format on
23#endif
24
Jakub Staszak0c4468b2012-11-14 20:18:34 +000025using namespace llvm;
26using namespace sys;
27
28namespace {
29
Michal Gorny1b25ba02018-11-20 18:38:11 +000030bool IsMPROTECT() {
31#if defined(__NetBSD__)
32 int mib[3];
33 int paxflags;
34 size_t len = sizeof(paxflags);
35
36 mib[0] = CTL_PROC;
37 mib[1] = getpid();
38 mib[2] = PROC_PID_PAXFLAGS;
39
40 if (sysctl(mib, 3, &paxflags, &len, NULL, 0) != 0)
41 err(EXIT_FAILURE, "sysctl");
42
43 return !!(paxflags & CTL_PROC_PAXFLAGS_MPROTECT);
44#else
45 return false;
46#endif
47}
48
Jakub Staszak0c4468b2012-11-14 20:18:34 +000049class MappedMemoryTest : public ::testing::TestWithParam<unsigned> {
50public:
51 MappedMemoryTest() {
52 Flags = GetParam();
Lang Hamese4b4ab62019-05-08 02:11:07 +000053 PageSize = sys::Process::getPageSizeEstimate();
Jakub Staszak0c4468b2012-11-14 20:18:34 +000054 }
55
56protected:
57 // Adds RW flags to permit testing of the resulting memory
58 unsigned getTestableEquivalent(unsigned RequestedFlags) {
59 switch (RequestedFlags) {
60 case Memory::MF_READ:
61 case Memory::MF_WRITE:
62 case Memory::MF_READ|Memory::MF_WRITE:
63 return Memory::MF_READ|Memory::MF_WRITE;
64 case Memory::MF_READ|Memory::MF_EXEC:
65 case Memory::MF_READ|Memory::MF_WRITE|Memory::MF_EXEC:
66 case Memory::MF_EXEC:
67 return Memory::MF_READ|Memory::MF_WRITE|Memory::MF_EXEC;
68 }
69 // Default in case values are added to the enum, as required by some compilers
70 return Memory::MF_READ|Memory::MF_WRITE;
71 }
72
73 // Returns true if the memory blocks overlap
74 bool doesOverlap(MemoryBlock M1, MemoryBlock M2) {
75 if (M1.base() == M2.base())
76 return true;
77
78 if (M1.base() > M2.base())
79 return (unsigned char *)M2.base() + M2.size() > M1.base();
80
81 return (unsigned char *)M1.base() + M1.size() > M2.base();
82 }
83
84 unsigned Flags;
85 size_t PageSize;
86};
87
Michal Gorny1b25ba02018-11-20 18:38:11 +000088// MPROTECT prevents W+X mmaps
89#define CHECK_UNSUPPORTED() \
90 do { \
91 if ((Flags & Memory::MF_WRITE) && (Flags & Memory::MF_EXEC) && \
92 IsMPROTECT()) \
93 return; \
94 } while (0)
95
Jakub Staszak0c4468b2012-11-14 20:18:34 +000096TEST_P(MappedMemoryTest, AllocAndRelease) {
Michal Gorny1b25ba02018-11-20 18:38:11 +000097 CHECK_UNSUPPORTED();
Rafael Espindolac049c652014-06-13 03:20:08 +000098 std::error_code EC;
Craig Topper66f09ad2014-06-08 22:29:17 +000099 MemoryBlock M1 = Memory::allocateMappedMemory(sizeof(int), nullptr, Flags,EC);
Rafael Espindolac049c652014-06-13 03:20:08 +0000100 EXPECT_EQ(std::error_code(), EC);
Jakub Staszak0c4468b2012-11-14 20:18:34 +0000101
Craig Topper66f09ad2014-06-08 22:29:17 +0000102 EXPECT_NE((void*)nullptr, M1.base());
Jakub Staszak0c4468b2012-11-14 20:18:34 +0000103 EXPECT_LE(sizeof(int), M1.size());
104
105 EXPECT_FALSE(Memory::releaseMappedMemory(M1));
106}
107
Alexandre Ganeab05ba932019-02-28 02:47:34 +0000108TEST_P(MappedMemoryTest, AllocAndReleaseHuge) {
109 CHECK_UNSUPPORTED();
110 std::error_code EC;
111 MemoryBlock M1 = Memory::allocateMappedMemory(
112 sizeof(int), nullptr, Flags | Memory::MF_HUGE_HINT, EC);
113 EXPECT_EQ(std::error_code(), EC);
114
115 // Test large/huge memory pages. In the worst case, 4kb pages should be
116 // returned, if large pages aren't available.
117
118 EXPECT_NE((void *)nullptr, M1.base());
119 EXPECT_LE(sizeof(int), M1.size());
120
121 EXPECT_FALSE(Memory::releaseMappedMemory(M1));
122}
123
Jakub Staszak0c4468b2012-11-14 20:18:34 +0000124TEST_P(MappedMemoryTest, MultipleAllocAndRelease) {
Michal Gorny1b25ba02018-11-20 18:38:11 +0000125 CHECK_UNSUPPORTED();
Rafael Espindolac049c652014-06-13 03:20:08 +0000126 std::error_code EC;
Craig Topper66f09ad2014-06-08 22:29:17 +0000127 MemoryBlock M1 = Memory::allocateMappedMemory(16, nullptr, Flags, EC);
Rafael Espindolac049c652014-06-13 03:20:08 +0000128 EXPECT_EQ(std::error_code(), EC);
Craig Topper66f09ad2014-06-08 22:29:17 +0000129 MemoryBlock M2 = Memory::allocateMappedMemory(64, nullptr, Flags, EC);
Rafael Espindolac049c652014-06-13 03:20:08 +0000130 EXPECT_EQ(std::error_code(), EC);
Craig Topper66f09ad2014-06-08 22:29:17 +0000131 MemoryBlock M3 = Memory::allocateMappedMemory(32, nullptr, Flags, EC);
Rafael Espindolac049c652014-06-13 03:20:08 +0000132 EXPECT_EQ(std::error_code(), EC);
Jakub Staszak0c4468b2012-11-14 20:18:34 +0000133
Craig Topper66f09ad2014-06-08 22:29:17 +0000134 EXPECT_NE((void*)nullptr, M1.base());
Jakub Staszak0c4468b2012-11-14 20:18:34 +0000135 EXPECT_LE(16U, M1.size());
Craig Topper66f09ad2014-06-08 22:29:17 +0000136 EXPECT_NE((void*)nullptr, M2.base());
Jakub Staszak0c4468b2012-11-14 20:18:34 +0000137 EXPECT_LE(64U, M2.size());
Craig Topper66f09ad2014-06-08 22:29:17 +0000138 EXPECT_NE((void*)nullptr, M3.base());
Jakub Staszak0c4468b2012-11-14 20:18:34 +0000139 EXPECT_LE(32U, M3.size());
140
141 EXPECT_FALSE(doesOverlap(M1, M2));
142 EXPECT_FALSE(doesOverlap(M2, M3));
143 EXPECT_FALSE(doesOverlap(M1, M3));
144
145 EXPECT_FALSE(Memory::releaseMappedMemory(M1));
146 EXPECT_FALSE(Memory::releaseMappedMemory(M3));
Craig Topper66f09ad2014-06-08 22:29:17 +0000147 MemoryBlock M4 = Memory::allocateMappedMemory(16, nullptr, Flags, EC);
Rafael Espindolac049c652014-06-13 03:20:08 +0000148 EXPECT_EQ(std::error_code(), EC);
Craig Topper66f09ad2014-06-08 22:29:17 +0000149 EXPECT_NE((void*)nullptr, M4.base());
Jakub Staszak0c4468b2012-11-14 20:18:34 +0000150 EXPECT_LE(16U, M4.size());
151 EXPECT_FALSE(Memory::releaseMappedMemory(M4));
152 EXPECT_FALSE(Memory::releaseMappedMemory(M2));
153}
154
155TEST_P(MappedMemoryTest, BasicWrite) {
Akira Hatanaka4b11df02012-12-05 22:43:07 +0000156 // This test applies only to readable and writeable combinations
157 if (Flags &&
158 !((Flags & Memory::MF_READ) && (Flags & Memory::MF_WRITE)))
Jakub Staszak0c4468b2012-11-14 20:18:34 +0000159 return;
Michal Gorny1b25ba02018-11-20 18:38:11 +0000160 CHECK_UNSUPPORTED();
Jakub Staszak0c4468b2012-11-14 20:18:34 +0000161
Rafael Espindolac049c652014-06-13 03:20:08 +0000162 std::error_code EC;
Craig Topper66f09ad2014-06-08 22:29:17 +0000163 MemoryBlock M1 = Memory::allocateMappedMemory(sizeof(int), nullptr, Flags,EC);
Rafael Espindolac049c652014-06-13 03:20:08 +0000164 EXPECT_EQ(std::error_code(), EC);
Jakub Staszak0c4468b2012-11-14 20:18:34 +0000165
Craig Topper66f09ad2014-06-08 22:29:17 +0000166 EXPECT_NE((void*)nullptr, M1.base());
Jakub Staszak0c4468b2012-11-14 20:18:34 +0000167 EXPECT_LE(sizeof(int), M1.size());
168
169 int *a = (int*)M1.base();
170 *a = 1;
171 EXPECT_EQ(1, *a);
172
173 EXPECT_FALSE(Memory::releaseMappedMemory(M1));
174}
175
176TEST_P(MappedMemoryTest, MultipleWrite) {
Akira Hatanaka4b11df02012-12-05 22:43:07 +0000177 // This test applies only to readable and writeable combinations
178 if (Flags &&
179 !((Flags & Memory::MF_READ) && (Flags & Memory::MF_WRITE)))
Jakub Staszak0c4468b2012-11-14 20:18:34 +0000180 return;
Michal Gorny1b25ba02018-11-20 18:38:11 +0000181 CHECK_UNSUPPORTED();
182
Rafael Espindolac049c652014-06-13 03:20:08 +0000183 std::error_code EC;
Craig Topper66f09ad2014-06-08 22:29:17 +0000184 MemoryBlock M1 = Memory::allocateMappedMemory(sizeof(int), nullptr, Flags,
185 EC);
Rafael Espindolac049c652014-06-13 03:20:08 +0000186 EXPECT_EQ(std::error_code(), EC);
Craig Topper66f09ad2014-06-08 22:29:17 +0000187 MemoryBlock M2 = Memory::allocateMappedMemory(8 * sizeof(int), nullptr, Flags,
188 EC);
Rafael Espindolac049c652014-06-13 03:20:08 +0000189 EXPECT_EQ(std::error_code(), EC);
Craig Topper66f09ad2014-06-08 22:29:17 +0000190 MemoryBlock M3 = Memory::allocateMappedMemory(4 * sizeof(int), nullptr, Flags,
191 EC);
Rafael Espindolac049c652014-06-13 03:20:08 +0000192 EXPECT_EQ(std::error_code(), EC);
Jakub Staszak0c4468b2012-11-14 20:18:34 +0000193
194 EXPECT_FALSE(doesOverlap(M1, M2));
195 EXPECT_FALSE(doesOverlap(M2, M3));
196 EXPECT_FALSE(doesOverlap(M1, M3));
197
Craig Topper66f09ad2014-06-08 22:29:17 +0000198 EXPECT_NE((void*)nullptr, M1.base());
Jakub Staszak0c4468b2012-11-14 20:18:34 +0000199 EXPECT_LE(1U * sizeof(int), M1.size());
Craig Topper66f09ad2014-06-08 22:29:17 +0000200 EXPECT_NE((void*)nullptr, M2.base());
Jakub Staszak0c4468b2012-11-14 20:18:34 +0000201 EXPECT_LE(8U * sizeof(int), M2.size());
Craig Topper66f09ad2014-06-08 22:29:17 +0000202 EXPECT_NE((void*)nullptr, M3.base());
Jakub Staszak0c4468b2012-11-14 20:18:34 +0000203 EXPECT_LE(4U * sizeof(int), M3.size());
204
205 int *x = (int*)M1.base();
206 *x = 1;
207
208 int *y = (int*)M2.base();
209 for (int i = 0; i < 8; i++) {
210 y[i] = i;
211 }
212
213 int *z = (int*)M3.base();
214 *z = 42;
215
216 EXPECT_EQ(1, *x);
217 EXPECT_EQ(7, y[7]);
218 EXPECT_EQ(42, *z);
219
220 EXPECT_FALSE(Memory::releaseMappedMemory(M1));
221 EXPECT_FALSE(Memory::releaseMappedMemory(M3));
222
Craig Topper66f09ad2014-06-08 22:29:17 +0000223 MemoryBlock M4 = Memory::allocateMappedMemory(64 * sizeof(int), nullptr,
224 Flags, EC);
Rafael Espindolac049c652014-06-13 03:20:08 +0000225 EXPECT_EQ(std::error_code(), EC);
Craig Topper66f09ad2014-06-08 22:29:17 +0000226 EXPECT_NE((void*)nullptr, M4.base());
Jakub Staszak0c4468b2012-11-14 20:18:34 +0000227 EXPECT_LE(64U * sizeof(int), M4.size());
228 x = (int*)M4.base();
229 *x = 4;
230 EXPECT_EQ(4, *x);
231 EXPECT_FALSE(Memory::releaseMappedMemory(M4));
232
233 // Verify that M2 remains unaffected by other activity
234 for (int i = 0; i < 8; i++) {
235 EXPECT_EQ(i, y[i]);
236 }
237 EXPECT_FALSE(Memory::releaseMappedMemory(M2));
238}
239
240TEST_P(MappedMemoryTest, EnabledWrite) {
Michal Gorny1b25ba02018-11-20 18:38:11 +0000241 // MPROTECT prevents W+X, and since this test always adds W we need
242 // to block any variant with X.
243 if ((Flags & Memory::MF_EXEC) && IsMPROTECT())
244 return;
245
Rafael Espindolac049c652014-06-13 03:20:08 +0000246 std::error_code EC;
Craig Topper66f09ad2014-06-08 22:29:17 +0000247 MemoryBlock M1 = Memory::allocateMappedMemory(2 * sizeof(int), nullptr, Flags,
248 EC);
Rafael Espindolac049c652014-06-13 03:20:08 +0000249 EXPECT_EQ(std::error_code(), EC);
Craig Topper66f09ad2014-06-08 22:29:17 +0000250 MemoryBlock M2 = Memory::allocateMappedMemory(8 * sizeof(int), nullptr, Flags,
251 EC);
Rafael Espindolac049c652014-06-13 03:20:08 +0000252 EXPECT_EQ(std::error_code(), EC);
Craig Topper66f09ad2014-06-08 22:29:17 +0000253 MemoryBlock M3 = Memory::allocateMappedMemory(4 * sizeof(int), nullptr, Flags,
254 EC);
Rafael Espindolac049c652014-06-13 03:20:08 +0000255 EXPECT_EQ(std::error_code(), EC);
Jakub Staszak0c4468b2012-11-14 20:18:34 +0000256
Craig Topper66f09ad2014-06-08 22:29:17 +0000257 EXPECT_NE((void*)nullptr, M1.base());
Jakub Staszak0c4468b2012-11-14 20:18:34 +0000258 EXPECT_LE(2U * sizeof(int), M1.size());
Craig Topper66f09ad2014-06-08 22:29:17 +0000259 EXPECT_NE((void*)nullptr, M2.base());
Jakub Staszak0c4468b2012-11-14 20:18:34 +0000260 EXPECT_LE(8U * sizeof(int), M2.size());
Craig Topper66f09ad2014-06-08 22:29:17 +0000261 EXPECT_NE((void*)nullptr, M3.base());
Jakub Staszak0c4468b2012-11-14 20:18:34 +0000262 EXPECT_LE(4U * sizeof(int), M3.size());
263
264 EXPECT_FALSE(Memory::protectMappedMemory(M1, getTestableEquivalent(Flags)));
265 EXPECT_FALSE(Memory::protectMappedMemory(M2, getTestableEquivalent(Flags)));
266 EXPECT_FALSE(Memory::protectMappedMemory(M3, getTestableEquivalent(Flags)));
267
268 EXPECT_FALSE(doesOverlap(M1, M2));
269 EXPECT_FALSE(doesOverlap(M2, M3));
270 EXPECT_FALSE(doesOverlap(M1, M3));
271
272 int *x = (int*)M1.base();
273 *x = 1;
274 int *y = (int*)M2.base();
275 for (unsigned int i = 0; i < 8; i++) {
276 y[i] = i;
277 }
278 int *z = (int*)M3.base();
279 *z = 42;
280
281 EXPECT_EQ(1, *x);
282 EXPECT_EQ(7, y[7]);
283 EXPECT_EQ(42, *z);
284
285 EXPECT_FALSE(Memory::releaseMappedMemory(M1));
286 EXPECT_FALSE(Memory::releaseMappedMemory(M3));
287 EXPECT_EQ(6, y[6]);
288
Craig Topper66f09ad2014-06-08 22:29:17 +0000289 MemoryBlock M4 = Memory::allocateMappedMemory(16, nullptr, Flags, EC);
Rafael Espindolac049c652014-06-13 03:20:08 +0000290 EXPECT_EQ(std::error_code(), EC);
Craig Topper66f09ad2014-06-08 22:29:17 +0000291 EXPECT_NE((void*)nullptr, M4.base());
Jakub Staszak0c4468b2012-11-14 20:18:34 +0000292 EXPECT_LE(16U, M4.size());
Rafael Espindolac049c652014-06-13 03:20:08 +0000293 EXPECT_EQ(std::error_code(),
294 Memory::protectMappedMemory(M4, getTestableEquivalent(Flags)));
Jakub Staszak0c4468b2012-11-14 20:18:34 +0000295 x = (int*)M4.base();
296 *x = 4;
297 EXPECT_EQ(4, *x);
298 EXPECT_FALSE(Memory::releaseMappedMemory(M4));
299 EXPECT_FALSE(Memory::releaseMappedMemory(M2));
300}
301
302TEST_P(MappedMemoryTest, SuccessiveNear) {
Michal Gorny1b25ba02018-11-20 18:38:11 +0000303 CHECK_UNSUPPORTED();
Rafael Espindolac049c652014-06-13 03:20:08 +0000304 std::error_code EC;
Craig Topper66f09ad2014-06-08 22:29:17 +0000305 MemoryBlock M1 = Memory::allocateMappedMemory(16, nullptr, Flags, EC);
Rafael Espindolac049c652014-06-13 03:20:08 +0000306 EXPECT_EQ(std::error_code(), EC);
Jakub Staszak0c4468b2012-11-14 20:18:34 +0000307 MemoryBlock M2 = Memory::allocateMappedMemory(64, &M1, Flags, EC);
Rafael Espindolac049c652014-06-13 03:20:08 +0000308 EXPECT_EQ(std::error_code(), EC);
Jakub Staszak0c4468b2012-11-14 20:18:34 +0000309 MemoryBlock M3 = Memory::allocateMappedMemory(32, &M2, Flags, EC);
Rafael Espindolac049c652014-06-13 03:20:08 +0000310 EXPECT_EQ(std::error_code(), EC);
Jakub Staszak0c4468b2012-11-14 20:18:34 +0000311
Craig Topper66f09ad2014-06-08 22:29:17 +0000312 EXPECT_NE((void*)nullptr, M1.base());
Jakub Staszak0c4468b2012-11-14 20:18:34 +0000313 EXPECT_LE(16U, M1.size());
Craig Topper66f09ad2014-06-08 22:29:17 +0000314 EXPECT_NE((void*)nullptr, M2.base());
Jakub Staszak0c4468b2012-11-14 20:18:34 +0000315 EXPECT_LE(64U, M2.size());
Craig Topper66f09ad2014-06-08 22:29:17 +0000316 EXPECT_NE((void*)nullptr, M3.base());
Jakub Staszak0c4468b2012-11-14 20:18:34 +0000317 EXPECT_LE(32U, M3.size());
318
319 EXPECT_FALSE(doesOverlap(M1, M2));
320 EXPECT_FALSE(doesOverlap(M2, M3));
321 EXPECT_FALSE(doesOverlap(M1, M3));
322
323 EXPECT_FALSE(Memory::releaseMappedMemory(M1));
324 EXPECT_FALSE(Memory::releaseMappedMemory(M3));
325 EXPECT_FALSE(Memory::releaseMappedMemory(M2));
326}
327
328TEST_P(MappedMemoryTest, DuplicateNear) {
Michal Gorny1b25ba02018-11-20 18:38:11 +0000329 CHECK_UNSUPPORTED();
Rafael Espindolac049c652014-06-13 03:20:08 +0000330 std::error_code EC;
Jakub Staszak0c4468b2012-11-14 20:18:34 +0000331 MemoryBlock Near((void*)(3*PageSize), 16);
332 MemoryBlock M1 = Memory::allocateMappedMemory(16, &Near, Flags, EC);
Rafael Espindolac049c652014-06-13 03:20:08 +0000333 EXPECT_EQ(std::error_code(), EC);
Jakub Staszak0c4468b2012-11-14 20:18:34 +0000334 MemoryBlock M2 = Memory::allocateMappedMemory(64, &Near, Flags, EC);
Rafael Espindolac049c652014-06-13 03:20:08 +0000335 EXPECT_EQ(std::error_code(), EC);
Jakub Staszak0c4468b2012-11-14 20:18:34 +0000336 MemoryBlock M3 = Memory::allocateMappedMemory(32, &Near, Flags, EC);
Rafael Espindolac049c652014-06-13 03:20:08 +0000337 EXPECT_EQ(std::error_code(), EC);
Jakub Staszak0c4468b2012-11-14 20:18:34 +0000338
Craig Topper66f09ad2014-06-08 22:29:17 +0000339 EXPECT_NE((void*)nullptr, M1.base());
Jakub Staszak0c4468b2012-11-14 20:18:34 +0000340 EXPECT_LE(16U, M1.size());
Craig Topper66f09ad2014-06-08 22:29:17 +0000341 EXPECT_NE((void*)nullptr, M2.base());
Jakub Staszak0c4468b2012-11-14 20:18:34 +0000342 EXPECT_LE(64U, M2.size());
Craig Topper66f09ad2014-06-08 22:29:17 +0000343 EXPECT_NE((void*)nullptr, M3.base());
Jakub Staszak0c4468b2012-11-14 20:18:34 +0000344 EXPECT_LE(32U, M3.size());
345
346 EXPECT_FALSE(Memory::releaseMappedMemory(M1));
347 EXPECT_FALSE(Memory::releaseMappedMemory(M3));
348 EXPECT_FALSE(Memory::releaseMappedMemory(M2));
349}
350
351TEST_P(MappedMemoryTest, ZeroNear) {
Michal Gorny1b25ba02018-11-20 18:38:11 +0000352 CHECK_UNSUPPORTED();
Rafael Espindolac049c652014-06-13 03:20:08 +0000353 std::error_code EC;
Craig Topper66f09ad2014-06-08 22:29:17 +0000354 MemoryBlock Near(nullptr, 0);
Jakub Staszak0c4468b2012-11-14 20:18:34 +0000355 MemoryBlock M1 = Memory::allocateMappedMemory(16, &Near, Flags, EC);
Rafael Espindolac049c652014-06-13 03:20:08 +0000356 EXPECT_EQ(std::error_code(), EC);
Jakub Staszak0c4468b2012-11-14 20:18:34 +0000357 MemoryBlock M2 = Memory::allocateMappedMemory(64, &Near, Flags, EC);
Rafael Espindolac049c652014-06-13 03:20:08 +0000358 EXPECT_EQ(std::error_code(), EC);
Jakub Staszak0c4468b2012-11-14 20:18:34 +0000359 MemoryBlock M3 = Memory::allocateMappedMemory(32, &Near, Flags, EC);
Rafael Espindolac049c652014-06-13 03:20:08 +0000360 EXPECT_EQ(std::error_code(), EC);
Jakub Staszak0c4468b2012-11-14 20:18:34 +0000361
Craig Topper66f09ad2014-06-08 22:29:17 +0000362 EXPECT_NE((void*)nullptr, M1.base());
Jakub Staszak0c4468b2012-11-14 20:18:34 +0000363 EXPECT_LE(16U, M1.size());
Craig Topper66f09ad2014-06-08 22:29:17 +0000364 EXPECT_NE((void*)nullptr, M2.base());
Jakub Staszak0c4468b2012-11-14 20:18:34 +0000365 EXPECT_LE(64U, M2.size());
Craig Topper66f09ad2014-06-08 22:29:17 +0000366 EXPECT_NE((void*)nullptr, M3.base());
Jakub Staszak0c4468b2012-11-14 20:18:34 +0000367 EXPECT_LE(32U, M3.size());
368
369 EXPECT_FALSE(doesOverlap(M1, M2));
370 EXPECT_FALSE(doesOverlap(M2, M3));
371 EXPECT_FALSE(doesOverlap(M1, M3));
372
373 EXPECT_FALSE(Memory::releaseMappedMemory(M1));
374 EXPECT_FALSE(Memory::releaseMappedMemory(M3));
375 EXPECT_FALSE(Memory::releaseMappedMemory(M2));
376}
377
378TEST_P(MappedMemoryTest, ZeroSizeNear) {
Michal Gorny1b25ba02018-11-20 18:38:11 +0000379 CHECK_UNSUPPORTED();
Rafael Espindolac049c652014-06-13 03:20:08 +0000380 std::error_code EC;
Jakub Staszak0c4468b2012-11-14 20:18:34 +0000381 MemoryBlock Near((void*)(4*PageSize), 0);
382 MemoryBlock M1 = Memory::allocateMappedMemory(16, &Near, Flags, EC);
Rafael Espindolac049c652014-06-13 03:20:08 +0000383 EXPECT_EQ(std::error_code(), EC);
Jakub Staszak0c4468b2012-11-14 20:18:34 +0000384 MemoryBlock M2 = Memory::allocateMappedMemory(64, &Near, Flags, EC);
Rafael Espindolac049c652014-06-13 03:20:08 +0000385 EXPECT_EQ(std::error_code(), EC);
Jakub Staszak0c4468b2012-11-14 20:18:34 +0000386 MemoryBlock M3 = Memory::allocateMappedMemory(32, &Near, Flags, EC);
Rafael Espindolac049c652014-06-13 03:20:08 +0000387 EXPECT_EQ(std::error_code(), EC);
Jakub Staszak0c4468b2012-11-14 20:18:34 +0000388
Craig Topper66f09ad2014-06-08 22:29:17 +0000389 EXPECT_NE((void*)nullptr, M1.base());
Jakub Staszak0c4468b2012-11-14 20:18:34 +0000390 EXPECT_LE(16U, M1.size());
Craig Topper66f09ad2014-06-08 22:29:17 +0000391 EXPECT_NE((void*)nullptr, M2.base());
Jakub Staszak0c4468b2012-11-14 20:18:34 +0000392 EXPECT_LE(64U, M2.size());
Craig Topper66f09ad2014-06-08 22:29:17 +0000393 EXPECT_NE((void*)nullptr, M3.base());
Jakub Staszak0c4468b2012-11-14 20:18:34 +0000394 EXPECT_LE(32U, M3.size());
395
396 EXPECT_FALSE(doesOverlap(M1, M2));
397 EXPECT_FALSE(doesOverlap(M2, M3));
398 EXPECT_FALSE(doesOverlap(M1, M3));
399
400 EXPECT_FALSE(Memory::releaseMappedMemory(M1));
401 EXPECT_FALSE(Memory::releaseMappedMemory(M3));
402 EXPECT_FALSE(Memory::releaseMappedMemory(M2));
403}
404
405TEST_P(MappedMemoryTest, UnalignedNear) {
Michal Gorny1b25ba02018-11-20 18:38:11 +0000406 CHECK_UNSUPPORTED();
Rafael Espindolac049c652014-06-13 03:20:08 +0000407 std::error_code EC;
Jakub Staszak0c4468b2012-11-14 20:18:34 +0000408 MemoryBlock Near((void*)(2*PageSize+5), 0);
409 MemoryBlock M1 = Memory::allocateMappedMemory(15, &Near, Flags, EC);
Rafael Espindolac049c652014-06-13 03:20:08 +0000410 EXPECT_EQ(std::error_code(), EC);
Jakub Staszak0c4468b2012-11-14 20:18:34 +0000411
Craig Topper66f09ad2014-06-08 22:29:17 +0000412 EXPECT_NE((void*)nullptr, M1.base());
Jakub Staszak0c4468b2012-11-14 20:18:34 +0000413 EXPECT_LE(sizeof(int), M1.size());
414
415 EXPECT_FALSE(Memory::releaseMappedMemory(M1));
416}
417
418// Note that Memory::MF_WRITE is not supported exclusively across
419// operating systems and architectures and can imply MF_READ|MF_WRITE
420unsigned MemoryFlags[] = {
NAKAMURA Takumi6f43bd42017-10-18 13:31:28 +0000421 Memory::MF_READ,
422 Memory::MF_WRITE,
423 Memory::MF_READ|Memory::MF_WRITE,
424 Memory::MF_EXEC,
425 Memory::MF_READ|Memory::MF_EXEC,
426 Memory::MF_READ|Memory::MF_WRITE|Memory::MF_EXEC
427 };
Jakub Staszak0c4468b2012-11-14 20:18:34 +0000428
429INSTANTIATE_TEST_CASE_P(AllocationTests,
NAKAMURA Takumi6f43bd42017-10-18 13:31:28 +0000430 MappedMemoryTest,
431 ::testing::ValuesIn(MemoryFlags),);
Jakub Staszak0c4468b2012-11-14 20:18:34 +0000432
433} // anonymous namespace