blob: 2b59cd9a4addf66b7585130b910ac812bef1bf0a [file] [log] [blame]
Brian Carlstrom9004cb62013-07-26 15:48:31 -07001/*
2 * Copyright (C) 2013 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include "mem_map.h"
18
19#include "UniquePtr.h"
20#include "gtest/gtest.h"
21
22namespace art {
23
Hiroshi Yamauchifd7e7f12013-10-22 14:17:48 -070024class MemMapTest : public testing::Test {
25 public:
Ian Rogersef7d42f2014-01-06 12:55:46 -080026 static byte* BaseBegin(MemMap* mem_map) {
Hiroshi Yamauchifd7e7f12013-10-22 14:17:48 -070027 return reinterpret_cast<byte*>(mem_map->base_begin_);
28 }
Ian Rogersef7d42f2014-01-06 12:55:46 -080029 static size_t BaseSize(MemMap* mem_map) {
Hiroshi Yamauchifd7e7f12013-10-22 14:17:48 -070030 return mem_map->base_size_;
31 }
Ian Rogersef7d42f2014-01-06 12:55:46 -080032
33 static void RemapAtEndTest(bool low_4gb) {
34 std::string error_msg;
35 // Cast the page size to size_t.
36 const size_t page_size = static_cast<size_t>(kPageSize);
37 // Map a two-page memory region.
38 MemMap* m0 = MemMap::MapAnonymous("MemMapTest_RemapAtEndTest_map0",
39 nullptr,
40 2 * page_size,
41 PROT_READ | PROT_WRITE,
42 low_4gb,
43 &error_msg);
44 // Check its state and write to it.
45 byte* base0 = m0->Begin();
46 ASSERT_TRUE(base0 != nullptr) << error_msg;
47 size_t size0 = m0->Size();
48 EXPECT_EQ(m0->Size(), 2 * page_size);
49 EXPECT_EQ(BaseBegin(m0), base0);
50 EXPECT_EQ(BaseSize(m0), size0);
51 memset(base0, 42, 2 * page_size);
52 // Remap the latter half into a second MemMap.
53 MemMap* m1 = m0->RemapAtEnd(base0 + page_size,
54 "MemMapTest_RemapAtEndTest_map1",
55 PROT_READ | PROT_WRITE,
56 &error_msg);
57 // Check the states of the two maps.
58 EXPECT_EQ(m0->Begin(), base0) << error_msg;
59 EXPECT_EQ(m0->Size(), page_size);
60 EXPECT_EQ(BaseBegin(m0), base0);
61 EXPECT_EQ(BaseSize(m0), page_size);
62 byte* base1 = m1->Begin();
63 size_t size1 = m1->Size();
64 EXPECT_EQ(base1, base0 + page_size);
65 EXPECT_EQ(size1, page_size);
66 EXPECT_EQ(BaseBegin(m1), base1);
67 EXPECT_EQ(BaseSize(m1), size1);
68 // Write to the second region.
69 memset(base1, 43, page_size);
70 // Check the contents of the two regions.
71 for (size_t i = 0; i < page_size; ++i) {
72 EXPECT_EQ(base0[i], 42);
73 }
74 for (size_t i = 0; i < page_size; ++i) {
75 EXPECT_EQ(base1[i], 43);
76 }
77 // Unmap the first region.
78 delete m0;
79 // Make sure the second region is still accessible after the first
80 // region is unmapped.
81 for (size_t i = 0; i < page_size; ++i) {
82 EXPECT_EQ(base1[i], 43);
83 }
84 delete m1;
85 }
Hiroshi Yamauchifd7e7f12013-10-22 14:17:48 -070086};
Brian Carlstrom9004cb62013-07-26 15:48:31 -070087
88TEST_F(MemMapTest, MapAnonymousEmpty) {
Ian Rogers8d31bbd2013-10-13 10:44:14 -070089 std::string error_msg;
Brian Carlstrom9004cb62013-07-26 15:48:31 -070090 UniquePtr<MemMap> map(MemMap::MapAnonymous("MapAnonymousEmpty",
Ian Rogersef7d42f2014-01-06 12:55:46 -080091 nullptr,
Brian Carlstrom9004cb62013-07-26 15:48:31 -070092 0,
Ian Rogers8d31bbd2013-10-13 10:44:14 -070093 PROT_READ,
Ian Rogersef7d42f2014-01-06 12:55:46 -080094 false,
Ian Rogers8d31bbd2013-10-13 10:44:14 -070095 &error_msg));
Ian Rogersef7d42f2014-01-06 12:55:46 -080096 ASSERT_TRUE(map.get() != nullptr) << error_msg;
97 ASSERT_TRUE(error_msg.empty());
98 map.reset(MemMap::MapAnonymous("MapAnonymousEmpty",
99 nullptr,
100 kPageSize,
101 PROT_READ | PROT_WRITE,
102 false,
103 &error_msg));
104 ASSERT_TRUE(map.get() != nullptr) << error_msg;
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700105 ASSERT_TRUE(error_msg.empty());
Brian Carlstrom9004cb62013-07-26 15:48:31 -0700106}
107
Ian Rogersef7d42f2014-01-06 12:55:46 -0800108#ifdef __LP64__
109TEST_F(MemMapTest, MapAnonymousEmpty32bit) {
Hiroshi Yamauchifd7e7f12013-10-22 14:17:48 -0700110 std::string error_msg;
Ian Rogersef7d42f2014-01-06 12:55:46 -0800111 UniquePtr<MemMap> map(MemMap::MapAnonymous("MapAnonymousEmpty",
112 nullptr,
113 kPageSize,
114 PROT_READ | PROT_WRITE,
115 true,
116 &error_msg));
117 ASSERT_TRUE(map.get() != nullptr) << error_msg;
118 ASSERT_TRUE(error_msg.empty());
119 ASSERT_LT(reinterpret_cast<uintptr_t>(BaseBegin(map.get())), 1ULL << 32);
Hiroshi Yamauchifd7e7f12013-10-22 14:17:48 -0700120}
Ian Rogersef7d42f2014-01-06 12:55:46 -0800121#endif
122
Hiroshi Yamauchi4fb5df82014-03-13 15:10:27 -0700123TEST_F(MemMapTest, MapAnonymousExactAddr) {
124 std::string error_msg;
125 // Map at an address that should work, which should succeed.
126 UniquePtr<MemMap> map0(MemMap::MapAnonymous("MapAnonymous0",
127 reinterpret_cast<byte*>(ART_BASE_ADDRESS),
128 kPageSize,
129 PROT_READ | PROT_WRITE,
130 false,
131 &error_msg));
132 ASSERT_TRUE(map0.get() != nullptr) << error_msg;
133 ASSERT_TRUE(error_msg.empty());
134 ASSERT_TRUE(map0->BaseBegin() == reinterpret_cast<void*>(ART_BASE_ADDRESS));
135 // Map at an unspecified address, which should succeed.
136 UniquePtr<MemMap> map1(MemMap::MapAnonymous("MapAnonymous1",
137 nullptr,
138 kPageSize,
139 PROT_READ | PROT_WRITE,
140 false,
141 &error_msg));
142 ASSERT_TRUE(map1.get() != nullptr) << error_msg;
143 ASSERT_TRUE(error_msg.empty());
144 ASSERT_TRUE(map1->BaseBegin() != nullptr);
145 // Attempt to map at the same address, which should fail.
146 UniquePtr<MemMap> map2(MemMap::MapAnonymous("MapAnonymous2",
147 reinterpret_cast<byte*>(map1->BaseBegin()),
148 kPageSize,
149 PROT_READ | PROT_WRITE,
150 false,
151 &error_msg));
152 ASSERT_TRUE(map2.get() == nullptr) << error_msg;
153 ASSERT_TRUE(!error_msg.empty());
154}
155
Ian Rogersef7d42f2014-01-06 12:55:46 -0800156TEST_F(MemMapTest, RemapAtEnd) {
157 RemapAtEndTest(false);
158}
159
160#ifdef __LP64__
161TEST_F(MemMapTest, RemapAtEnd32bit) {
162 RemapAtEndTest(true);
163}
164#endif
Hiroshi Yamauchifd7e7f12013-10-22 14:17:48 -0700165
Qiming Shi84d49cc2014-04-24 15:38:41 +0800166TEST_F(MemMapTest, MapAnonymousExactAddr32bitHighAddr) {
167 std::string error_msg;
168 UniquePtr<MemMap> map(MemMap::MapAnonymous("MapAnonymousExactAddr32bitHighAddr",
169 reinterpret_cast<byte*>(0x71000000),
170 0x21000000,
171 PROT_READ | PROT_WRITE,
172 true,
173 &error_msg));
174 ASSERT_TRUE(map.get() != nullptr) << error_msg;
175 ASSERT_TRUE(error_msg.empty());
176 ASSERT_EQ(reinterpret_cast<uintptr_t>(BaseBegin(map.get())), 0x71000000U);
177}
178
179TEST_F(MemMapTest, MapAnonymousOverflow) {
180 std::string error_msg;
181 uintptr_t ptr = 0;
182 ptr -= kPageSize; // Now it's close to the top.
183 UniquePtr<MemMap> map(MemMap::MapAnonymous("MapAnonymousOverflow",
184 reinterpret_cast<byte*>(ptr),
185 2 * kPageSize, // brings it over the top.
186 PROT_READ | PROT_WRITE,
187 false,
188 &error_msg));
189 ASSERT_EQ(nullptr, map.get());
190 ASSERT_FALSE(error_msg.empty());
191}
192
193#ifdef __LP64__
194TEST_F(MemMapTest, MapAnonymousLow4GBExpectedTooHigh) {
195 std::string error_msg;
196 UniquePtr<MemMap> map(MemMap::MapAnonymous("MapAnonymousLow4GBExpectedTooHigh",
197 reinterpret_cast<byte*>(UINT64_C(0x100000000)),
198 kPageSize,
199 PROT_READ | PROT_WRITE,
200 true,
201 &error_msg));
202 ASSERT_EQ(nullptr, map.get());
203 ASSERT_FALSE(error_msg.empty());
204}
205
206TEST_F(MemMapTest, MapAnonymousLow4GBRangeTooHigh) {
207 std::string error_msg;
208 UniquePtr<MemMap> map(MemMap::MapAnonymous("MapAnonymousLow4GBRangeTooHigh",
209 reinterpret_cast<byte*>(0xF0000000),
210 0x20000000,
211 PROT_READ | PROT_WRITE,
212 true,
213 &error_msg));
214 ASSERT_EQ(nullptr, map.get());
215 ASSERT_FALSE(error_msg.empty());
216}
217#endif
218
Brian Carlstrom9004cb62013-07-26 15:48:31 -0700219} // namespace art