1 : /*
2 : * Copyright 2008 The Native Client Authors. All rights reserved.
3 : * Use of this source code is governed by a BSD-style license that can
4 : * be found in the LICENSE file.
5 : */
6 :
7 : #include "native_client/src/include/nacl_platform.h"
8 : #include "native_client/src/trusted/service_runtime/sel_mem.h"
9 : #include "native_client/src/shared/platform/nacl_log.h"
10 : #include "gtest/gtest.h"
11 :
12 8 : class SelMemTest : public testing::Test {
13 : protected:
14 : virtual void SetUp();
15 : virtual void TearDown();
16 : };
17 :
18 4 : void SelMemTest::SetUp() {
19 4 : NaClLogModuleInit();
20 4 : }
21 :
22 4 : void SelMemTest::TearDown() {
23 4 : NaClLogModuleFini();
24 4 : }
25 :
26 4 : TEST_F(SelMemTest, AddTest) {
27 : struct NaClVmmap mem_map;
28 1 : int start_page_num = 32;
29 : int ret_code;
30 :
31 1 : ret_code = NaClVmmapCtor(&mem_map);
32 1 : EXPECT_EQ(1, ret_code);
33 :
34 12 : for (int i = 1; i <= 5; ++i) {
35 : ret_code = NaClVmmapAdd(&mem_map,
36 : start_page_num*i,
37 : i,
38 : PROT_READ | PROT_EXEC,
39 5 : (struct NaClMemObj *) NULL);
40 5 : EXPECT_EQ(1, ret_code);
41 5 : EXPECT_EQ(i, static_cast<int>(mem_map.nvalid));
42 5 : EXPECT_EQ(5, static_cast<int>(mem_map.size));
43 : }
44 :
45 : // no checks for start_page_num ..
46 : ret_code = NaClVmmapAdd(&mem_map,
47 : start_page_num,
48 : 2,
49 : PROT_READ,
50 1 : (struct NaClMemObj *) NULL);
51 1 : EXPECT_EQ(6, static_cast<int>(mem_map.nvalid));
52 1 : EXPECT_EQ(10, static_cast<int>(mem_map.size));
53 :
54 1 : NaClVmmapDtor(&mem_map);
55 1 : }
56 :
57 4 : TEST_F(SelMemTest, UpdateTest) {
58 : struct NaClVmmap mem_map;
59 :
60 1 : EXPECT_EQ(1, NaClVmmapCtor(&mem_map));
61 :
62 : // 1st region
63 : NaClVmmapUpdate(&mem_map,
64 : 32,
65 : 12,
66 : PROT_READ | PROT_EXEC,
67 : (struct NaClMemObj *) NULL,
68 1 : 0);
69 1 : EXPECT_EQ(1, static_cast<int>(mem_map.nvalid));
70 :
71 : // no overlap
72 : NaClVmmapUpdate(&mem_map,
73 : 64,
74 : 10,
75 : PROT_READ,
76 : (struct NaClMemObj *) NULL,
77 1 : 0);
78 : // vmmap is [32, 44], [64, 74]
79 1 : EXPECT_EQ(2, static_cast<int>(mem_map.nvalid));
80 :
81 : // new mapping overlaps end and start of existing mappings
82 : NaClVmmapUpdate(&mem_map,
83 : 42,
84 : 24,
85 : PROT_READ,
86 : (struct NaClMemObj *) NULL,
87 1 : 0);
88 : // vmmap is [32, 41], [42, 66], [67, 74]
89 1 : EXPECT_EQ(3, static_cast<int>(mem_map.nvalid));
90 :
91 : // new mapping is in the middle of existing mapping
92 : NaClVmmapUpdate(&mem_map,
93 : 36,
94 : 2,
95 : PROT_READ | PROT_EXEC,
96 : (struct NaClMemObj *) NULL,
97 1 : 0);
98 : // vmmap is [32, 35], [34, 36], [37, 41], [42, 66], [67, 74]
99 1 : EXPECT_EQ(5, static_cast<int>(mem_map.nvalid));
100 :
101 : // new mapping covers all of the existing mapping
102 : NaClVmmapUpdate(&mem_map,
103 : 32,
104 : 6,
105 : PROT_READ | PROT_EXEC,
106 : (struct NaClMemObj *) NULL,
107 1 : 0);
108 : // vmmap is [32, 36], [37, 41], [42, 66], [67, 74]
109 1 : EXPECT_EQ(4, static_cast<int>(mem_map.nvalid));
110 :
111 : // remove existing mappings
112 : NaClVmmapUpdate(&mem_map,
113 : 40,
114 : 30,
115 : PROT_READ | PROT_EXEC,
116 : (struct NaClMemObj *) NULL,
117 1 : 1);
118 : // vmmap is [32, 36], [37, 39], [71, 74]
119 1 : EXPECT_EQ(3, static_cast<int>(mem_map.nvalid));
120 :
121 1 : NaClVmmapDtor(&mem_map);
122 1 : }
123 :
124 4 : TEST_F(SelMemTest, FindPageTest) {
125 : struct NaClVmmap mem_map;
126 : int ret_code;
127 :
128 1 : ret_code = NaClVmmapCtor(&mem_map);
129 1 : EXPECT_EQ(1, ret_code);
130 :
131 : struct NaClVmmapEntry const *entry;
132 1 : entry = NaClVmmapFindPage(&mem_map, 32);
133 1 : EXPECT_TRUE(NULL == entry);
134 :
135 1 : int start_page_num = 32;
136 14 : for (int i = 1; i <= 6; ++i) {
137 : ret_code = NaClVmmapAdd(&mem_map,
138 : start_page_num*i,
139 : 2*i,
140 : PROT_READ | PROT_EXEC,
141 6 : (struct NaClMemObj *) NULL);
142 6 : EXPECT_EQ(1, ret_code);
143 6 : EXPECT_EQ(i, static_cast<int>(mem_map.nvalid));
144 : }
145 : // vmmap is [32, 34], [64, 68], [96, 102], [128, 136],
146 : // [160, 170], [192, 204]
147 :
148 1 : entry = NaClVmmapFindPage(&mem_map, 16);
149 1 : EXPECT_TRUE(NULL == entry);
150 :
151 1 : entry = NaClVmmapFindPage(&mem_map, 32);
152 1 : EXPECT_TRUE(NULL != entry);
153 :
154 1 : entry = NaClVmmapFindPage(&mem_map, 34);
155 1 : EXPECT_TRUE(NULL == entry);
156 :
157 1 : entry = NaClVmmapFindPage(&mem_map, 202);
158 1 : EXPECT_TRUE(NULL != entry);
159 :
160 1 : NaClVmmapDtor(&mem_map);
161 1 : }
162 :
163 4 : TEST_F(SelMemTest, FindSpaceTest) {
164 : struct NaClVmmap mem_map;
165 : uintptr_t ret_code;
166 :
167 1 : ret_code = NaClVmmapCtor(&mem_map);
168 1 : EXPECT_EQ(1U, ret_code);
169 :
170 : // no entry
171 1 : ret_code = NaClVmmapFindSpace(&mem_map, 32);
172 1 : EXPECT_EQ(0U, ret_code);
173 :
174 1 : EXPECT_EQ(1, NaClVmmapAdd(&mem_map,
175 : 32,
176 : 10,
177 : PROT_READ | PROT_EXEC,
178 : (struct NaClMemObj *) NULL));
179 1 : EXPECT_EQ(1, static_cast<int>(mem_map.nvalid));
180 : // one entry only
181 1 : ret_code = NaClVmmapFindSpace(&mem_map, 2);
182 1 : EXPECT_EQ(0U, ret_code);
183 :
184 1 : EXPECT_EQ(1, NaClVmmapAdd(&mem_map,
185 : 64,
186 : 10,
187 : PROT_READ | PROT_EXEC,
188 : (struct NaClMemObj *) NULL));
189 1 : EXPECT_EQ(2U, mem_map.nvalid);
190 :
191 : // the space is [32, 42], [64, 74]
192 1 : ret_code = NaClVmmapFindSpace(&mem_map, 32);
193 1 : EXPECT_EQ(0U, ret_code);
194 :
195 1 : ret_code = NaClVmmapFindSpace(&mem_map, 2);
196 1 : EXPECT_EQ(62U, ret_code);
197 :
198 1 : EXPECT_EQ(1, NaClVmmapAdd(&mem_map,
199 : 96,
200 : 10,
201 : PROT_READ | PROT_EXEC,
202 : (struct NaClMemObj *) NULL));
203 1 : EXPECT_EQ(3U, mem_map.nvalid);
204 :
205 : // vmmap is [32, 42], [64, 74], [96, 106]
206 : // the search is from high address down
207 1 : ret_code = NaClVmmapFindSpace(&mem_map, 22);
208 1 : EXPECT_EQ(74U, ret_code);
209 :
210 1 : NaClVmmapDtor(&mem_map);
211 3 : }
|