xref: /aosp_15_r20/system/unwinding/libunwindstack/tests/MapsTest.cpp (revision eb293b8f56ee8303637c5595cfcdeef8039e85c6)
1*eb293b8fSAndroid Build Coastguard Worker /*
2*eb293b8fSAndroid Build Coastguard Worker  * Copyright (C) 2016 The Android Open Source Project
3*eb293b8fSAndroid Build Coastguard Worker  *
4*eb293b8fSAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*eb293b8fSAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*eb293b8fSAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*eb293b8fSAndroid Build Coastguard Worker  *
8*eb293b8fSAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*eb293b8fSAndroid Build Coastguard Worker  *
10*eb293b8fSAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*eb293b8fSAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*eb293b8fSAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*eb293b8fSAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*eb293b8fSAndroid Build Coastguard Worker  * limitations under the License.
15*eb293b8fSAndroid Build Coastguard Worker  */
16*eb293b8fSAndroid Build Coastguard Worker 
17*eb293b8fSAndroid Build Coastguard Worker #include <inttypes.h>
18*eb293b8fSAndroid Build Coastguard Worker #include <sys/mman.h>
19*eb293b8fSAndroid Build Coastguard Worker 
20*eb293b8fSAndroid Build Coastguard Worker #include <android-base/file.h>
21*eb293b8fSAndroid Build Coastguard Worker #include <android-base/stringprintf.h>
22*eb293b8fSAndroid Build Coastguard Worker #include <gtest/gtest.h>
23*eb293b8fSAndroid Build Coastguard Worker 
24*eb293b8fSAndroid Build Coastguard Worker #include <unwindstack/Maps.h>
25*eb293b8fSAndroid Build Coastguard Worker 
26*eb293b8fSAndroid Build Coastguard Worker namespace unwindstack {
27*eb293b8fSAndroid Build Coastguard Worker 
VerifyLine(std::string line,MapInfo * info)28*eb293b8fSAndroid Build Coastguard Worker static void VerifyLine(std::string line, MapInfo* info) {
29*eb293b8fSAndroid Build Coastguard Worker   BufferMaps maps(line.c_str());
30*eb293b8fSAndroid Build Coastguard Worker 
31*eb293b8fSAndroid Build Coastguard Worker   if (info == nullptr) {
32*eb293b8fSAndroid Build Coastguard Worker     ASSERT_FALSE(maps.Parse()) << "Failed on: " + line;
33*eb293b8fSAndroid Build Coastguard Worker   } else {
34*eb293b8fSAndroid Build Coastguard Worker     ASSERT_TRUE(maps.Parse()) << "Failed on: " + line;
35*eb293b8fSAndroid Build Coastguard Worker     MapInfo* element = maps.Get(0).get();
36*eb293b8fSAndroid Build Coastguard Worker     ASSERT_TRUE(element != nullptr) << "Failed on: " + line;
37*eb293b8fSAndroid Build Coastguard Worker     info->set_start(element->start());
38*eb293b8fSAndroid Build Coastguard Worker     info->set_end(element->end());
39*eb293b8fSAndroid Build Coastguard Worker     info->set_offset(element->offset());
40*eb293b8fSAndroid Build Coastguard Worker     info->set_flags(element->flags());
41*eb293b8fSAndroid Build Coastguard Worker     info->set_name(element->name());
42*eb293b8fSAndroid Build Coastguard Worker     info->set_elf_offset(element->elf_offset());
43*eb293b8fSAndroid Build Coastguard Worker   }
44*eb293b8fSAndroid Build Coastguard Worker }
45*eb293b8fSAndroid Build Coastguard Worker 
TEST(MapsTest,map_add)46*eb293b8fSAndroid Build Coastguard Worker TEST(MapsTest, map_add) {
47*eb293b8fSAndroid Build Coastguard Worker   Maps maps;
48*eb293b8fSAndroid Build Coastguard Worker 
49*eb293b8fSAndroid Build Coastguard Worker   maps.Add(0x1000, 0x2000, 0, PROT_READ, "fake_map", 0);
50*eb293b8fSAndroid Build Coastguard Worker   maps.Add(0x3000, 0x4000, 0, 0, "", 0x1234);
51*eb293b8fSAndroid Build Coastguard Worker   maps.Add(0x5000, 0x6000, 1, 2, "fake_map", static_cast<uint64_t>(-1));
52*eb293b8fSAndroid Build Coastguard Worker 
53*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(3U, maps.Total());
54*eb293b8fSAndroid Build Coastguard Worker   auto info1 = maps.Get(0);
55*eb293b8fSAndroid Build Coastguard Worker   auto info2 = maps.Get(1);
56*eb293b8fSAndroid Build Coastguard Worker   auto info3 = maps.Get(2);
57*eb293b8fSAndroid Build Coastguard Worker 
58*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(nullptr, info1->prev_map());
59*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(nullptr, info1->GetPrevRealMap());
60*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(info2, info1->next_map());
61*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(info3, info1->GetNextRealMap());
62*eb293b8fSAndroid Build Coastguard Worker 
63*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(info1, info2->prev_map());
64*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(nullptr, info2->GetPrevRealMap());
65*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(info3, info2->next_map());
66*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(nullptr, info2->GetNextRealMap());
67*eb293b8fSAndroid Build Coastguard Worker 
68*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(info2, info3->prev_map());
69*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(info1, info3->GetPrevRealMap());
70*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(nullptr, info3->next_map());
71*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(nullptr, info3->GetNextRealMap());
72*eb293b8fSAndroid Build Coastguard Worker 
73*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0x1000U, info1->start());
74*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0x2000U, info1->end());
75*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0U, info1->offset());
76*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(PROT_READ, info1->flags());
77*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ("fake_map", info1->name());
78*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0U, info1->elf_offset());
79*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0U, info1->load_bias().load());
80*eb293b8fSAndroid Build Coastguard Worker }
81*eb293b8fSAndroid Build Coastguard Worker 
TEST(MapsTest,map_move)82*eb293b8fSAndroid Build Coastguard Worker TEST(MapsTest, map_move) {
83*eb293b8fSAndroid Build Coastguard Worker   Maps maps;
84*eb293b8fSAndroid Build Coastguard Worker 
85*eb293b8fSAndroid Build Coastguard Worker   maps.Add(0x1000, 0x2000, 0, PROT_READ, "fake_map", 0);
86*eb293b8fSAndroid Build Coastguard Worker   maps.Add(0x3000, 0x4000, 0x10, 0, "", 0x1234);
87*eb293b8fSAndroid Build Coastguard Worker   maps.Add(0x5000, 0x6000, 1, 2, "fake_map2", static_cast<uint64_t>(-1));
88*eb293b8fSAndroid Build Coastguard Worker 
89*eb293b8fSAndroid Build Coastguard Worker   Maps maps2 = std::move(maps);
90*eb293b8fSAndroid Build Coastguard Worker 
91*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(3U, maps2.Total());
92*eb293b8fSAndroid Build Coastguard Worker   auto info = maps2.Get(0);
93*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0x1000U, info->start());
94*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0x2000U, info->end());
95*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0U, info->offset());
96*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(PROT_READ, info->flags());
97*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ("fake_map", info->name());
98*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0U, info->elf_offset());
99*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0U, info->load_bias().load());
100*eb293b8fSAndroid Build Coastguard Worker }
101*eb293b8fSAndroid Build Coastguard Worker 
TEST(MapsTest,verify_parse_line)102*eb293b8fSAndroid Build Coastguard Worker TEST(MapsTest, verify_parse_line) {
103*eb293b8fSAndroid Build Coastguard Worker   auto info = MapInfo::Create(0, 0, 0, 0, "");
104*eb293b8fSAndroid Build Coastguard Worker 
105*eb293b8fSAndroid Build Coastguard Worker   VerifyLine("01-02 rwxp 03 04:05 06\n", info.get());
106*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(1U, info->start());
107*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(2U, info->end());
108*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(PROT_READ | PROT_WRITE | PROT_EXEC, info->flags());
109*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(3U, info->offset());
110*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ("", info->name());
111*eb293b8fSAndroid Build Coastguard Worker 
112*eb293b8fSAndroid Build Coastguard Worker   VerifyLine("0a-0b ---s 0c 0d:0e 06 /fake/name\n", info.get());
113*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0xaU, info->start());
114*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0xbU, info->end());
115*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0U, info->flags());
116*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0xcU, info->offset());
117*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ("/fake/name", info->name());
118*eb293b8fSAndroid Build Coastguard Worker 
119*eb293b8fSAndroid Build Coastguard Worker   VerifyLine("01-02   rwxp   03    04:05    06    /fake/name/again\n", info.get());
120*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(1U, info->start());
121*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(2U, info->end());
122*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(PROT_READ | PROT_WRITE | PROT_EXEC, info->flags());
123*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(3U, info->offset());
124*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ("/fake/name/again", info->name());
125*eb293b8fSAndroid Build Coastguard Worker 
126*eb293b8fSAndroid Build Coastguard Worker   VerifyLine("-00 rwxp 00 00:00 0\n", nullptr);
127*eb293b8fSAndroid Build Coastguard Worker   VerifyLine("00- rwxp 00 00:00 0\n", nullptr);
128*eb293b8fSAndroid Build Coastguard Worker   VerifyLine("00-00 rwxp 00 :00 0\n", nullptr);
129*eb293b8fSAndroid Build Coastguard Worker   VerifyLine("00-00 rwxp 00 00:00 \n", nullptr);
130*eb293b8fSAndroid Build Coastguard Worker   VerifyLine("x-00 rwxp 00 00:00 0\n", nullptr);
131*eb293b8fSAndroid Build Coastguard Worker   VerifyLine("00 -00 rwxp 00 00:00 0\n", nullptr);
132*eb293b8fSAndroid Build Coastguard Worker   VerifyLine("00-x rwxp 00 00:00 0\n", nullptr);
133*eb293b8fSAndroid Build Coastguard Worker   VerifyLine("00-x rwxp 00 00:00 0\n", nullptr);
134*eb293b8fSAndroid Build Coastguard Worker   VerifyLine("00-00x rwxp 00 00:00 0\n", nullptr);
135*eb293b8fSAndroid Build Coastguard Worker   VerifyLine("00-00 rwxp0 00 00:00 0\n", nullptr);
136*eb293b8fSAndroid Build Coastguard Worker   VerifyLine("00-00 rwxp0 00 00:00 0\n", nullptr);
137*eb293b8fSAndroid Build Coastguard Worker   VerifyLine("00-00 rwp 00 00:00 0\n", nullptr);
138*eb293b8fSAndroid Build Coastguard Worker   VerifyLine("00-00 rwxp 0000:00 0\n", nullptr);
139*eb293b8fSAndroid Build Coastguard Worker   VerifyLine("00-00 rwxp 00 00 :00 0\n", nullptr);
140*eb293b8fSAndroid Build Coastguard Worker   VerifyLine("00-00 rwxp 00 00: 00 0\n", nullptr);
141*eb293b8fSAndroid Build Coastguard Worker   VerifyLine("00-00 rwxp 00 00:000\n", nullptr);
142*eb293b8fSAndroid Build Coastguard Worker   VerifyLine("00-00 rwxp 00 00:00 0/fake\n", nullptr);
143*eb293b8fSAndroid Build Coastguard Worker   VerifyLine("00-00 xxxx 00 00:00 0 /fake\n", nullptr);
144*eb293b8fSAndroid Build Coastguard Worker   VerifyLine("00-00 ywxp 00 00:00 0 /fake\n", nullptr);
145*eb293b8fSAndroid Build Coastguard Worker   VerifyLine("00-00 ryxp 00 00:00 0 /fake\n", nullptr);
146*eb293b8fSAndroid Build Coastguard Worker   VerifyLine("00-00 rwyp 00 00:00 0 /fake\n", nullptr);
147*eb293b8fSAndroid Build Coastguard Worker   VerifyLine("00-00 rwx- 00 00:00 0 /fake\n", nullptr);
148*eb293b8fSAndroid Build Coastguard Worker   VerifyLine("0\n", nullptr);
149*eb293b8fSAndroid Build Coastguard Worker   VerifyLine("00\n", nullptr);
150*eb293b8fSAndroid Build Coastguard Worker   VerifyLine("00-\n", nullptr);
151*eb293b8fSAndroid Build Coastguard Worker   VerifyLine("00-0\n", nullptr);
152*eb293b8fSAndroid Build Coastguard Worker   VerifyLine("00-00\n", nullptr);
153*eb293b8fSAndroid Build Coastguard Worker   VerifyLine("00-00 \n", nullptr);
154*eb293b8fSAndroid Build Coastguard Worker   VerifyLine("00-00 -\n", nullptr);
155*eb293b8fSAndroid Build Coastguard Worker   VerifyLine("00-00 r\n", nullptr);
156*eb293b8fSAndroid Build Coastguard Worker   VerifyLine("00-00 --\n", nullptr);
157*eb293b8fSAndroid Build Coastguard Worker   VerifyLine("00-00 rw\n", nullptr);
158*eb293b8fSAndroid Build Coastguard Worker   VerifyLine("00-00 ---\n", nullptr);
159*eb293b8fSAndroid Build Coastguard Worker   VerifyLine("00-00 rwx\n", nullptr);
160*eb293b8fSAndroid Build Coastguard Worker   VerifyLine("00-00 ---s\n", nullptr);
161*eb293b8fSAndroid Build Coastguard Worker   VerifyLine("00-00 ---p\n", nullptr);
162*eb293b8fSAndroid Build Coastguard Worker   VerifyLine("00-00 ---s 0\n", nullptr);
163*eb293b8fSAndroid Build Coastguard Worker   VerifyLine("00-00 ---p 0 \n", nullptr);
164*eb293b8fSAndroid Build Coastguard Worker   VerifyLine("00-00 ---p 0 0\n", nullptr);
165*eb293b8fSAndroid Build Coastguard Worker   VerifyLine("00-00 ---p 0 0:\n", nullptr);
166*eb293b8fSAndroid Build Coastguard Worker   VerifyLine("00-00 ---p 0 0:0\n", nullptr);
167*eb293b8fSAndroid Build Coastguard Worker   VerifyLine("00-00 ---p 0 0:0 \n", nullptr);
168*eb293b8fSAndroid Build Coastguard Worker 
169*eb293b8fSAndroid Build Coastguard Worker   // Line to verify that the parser will detect a completely malformed line
170*eb293b8fSAndroid Build Coastguard Worker   // properly.
171*eb293b8fSAndroid Build Coastguard Worker   VerifyLine("7ffff7dda000-7ffff7dfd7ffff7ff3000-7ffff7ff4000 ---p 0000f000 fc:02 44171565\n",
172*eb293b8fSAndroid Build Coastguard Worker              nullptr);
173*eb293b8fSAndroid Build Coastguard Worker }
174*eb293b8fSAndroid Build Coastguard Worker 
TEST(MapsTest,verify_large_values)175*eb293b8fSAndroid Build Coastguard Worker TEST(MapsTest, verify_large_values) {
176*eb293b8fSAndroid Build Coastguard Worker   auto info = MapInfo::Create(0, 0, 0, 0, "");
177*eb293b8fSAndroid Build Coastguard Worker #if defined(__LP64__)
178*eb293b8fSAndroid Build Coastguard Worker   VerifyLine("fabcdef012345678-f12345678abcdef8 rwxp f0b0d0f010305070 00:00 0\n", info.get());
179*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0xfabcdef012345678UL, info->start());
180*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0xf12345678abcdef8UL, info->end());
181*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(PROT_READ | PROT_WRITE | PROT_EXEC, info->flags());
182*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0xf0b0d0f010305070UL, info->offset());
183*eb293b8fSAndroid Build Coastguard Worker #else
184*eb293b8fSAndroid Build Coastguard Worker   VerifyLine("f2345678-fabcdef8 rwxp f0305070 00:00 0\n", info.get());
185*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0xf2345678UL, info->start());
186*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0xfabcdef8UL, info->end());
187*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(PROT_READ | PROT_WRITE | PROT_EXEC, info->flags());
188*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0xf0305070UL, info->offset());
189*eb293b8fSAndroid Build Coastguard Worker #endif
190*eb293b8fSAndroid Build Coastguard Worker }
191*eb293b8fSAndroid Build Coastguard Worker 
TEST(MapsTest,parse_permissions)192*eb293b8fSAndroid Build Coastguard Worker TEST(MapsTest, parse_permissions) {
193*eb293b8fSAndroid Build Coastguard Worker   BufferMaps maps(
194*eb293b8fSAndroid Build Coastguard Worker       "1000-2000 ---s 00000000 00:00 0\n"
195*eb293b8fSAndroid Build Coastguard Worker       "2000-3000 r--s 00000000 00:00 0\n"
196*eb293b8fSAndroid Build Coastguard Worker       "3000-4000 -w-s 00000000 00:00 0\n"
197*eb293b8fSAndroid Build Coastguard Worker       "4000-5000 --xp 00000000 00:00 0\n"
198*eb293b8fSAndroid Build Coastguard Worker       "5000-6000 rwxp 00000000 00:00 0\n");
199*eb293b8fSAndroid Build Coastguard Worker 
200*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(maps.Parse());
201*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(5U, maps.Total());
202*eb293b8fSAndroid Build Coastguard Worker 
203*eb293b8fSAndroid Build Coastguard Worker   auto info = maps.Get(0);
204*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(info != nullptr);
205*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(PROT_NONE, info->flags());
206*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0x1000U, info->start());
207*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0x2000U, info->end());
208*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0U, info->offset());
209*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ("", info->name());
210*eb293b8fSAndroid Build Coastguard Worker 
211*eb293b8fSAndroid Build Coastguard Worker   info = maps.Get(1);
212*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(info != nullptr);
213*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(PROT_READ, info->flags());
214*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0x2000U, info->start());
215*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0x3000U, info->end());
216*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0U, info->offset());
217*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ("", info->name());
218*eb293b8fSAndroid Build Coastguard Worker 
219*eb293b8fSAndroid Build Coastguard Worker   info = maps.Get(2);
220*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(info != nullptr);
221*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(PROT_WRITE, info->flags());
222*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0x3000U, info->start());
223*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0x4000U, info->end());
224*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0U, info->offset());
225*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ("", info->name());
226*eb293b8fSAndroid Build Coastguard Worker 
227*eb293b8fSAndroid Build Coastguard Worker   info = maps.Get(3);
228*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(info != nullptr);
229*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(PROT_EXEC, info->flags());
230*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0x4000U, info->start());
231*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0x5000U, info->end());
232*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0U, info->offset());
233*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ("", info->name());
234*eb293b8fSAndroid Build Coastguard Worker 
235*eb293b8fSAndroid Build Coastguard Worker   info = maps.Get(4);
236*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(info != nullptr);
237*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(PROT_READ | PROT_WRITE | PROT_EXEC, info->flags());
238*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0x5000U, info->start());
239*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0x6000U, info->end());
240*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0U, info->offset());
241*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ("", info->name());
242*eb293b8fSAndroid Build Coastguard Worker 
243*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(maps.Get(5) == nullptr);
244*eb293b8fSAndroid Build Coastguard Worker }
245*eb293b8fSAndroid Build Coastguard Worker 
TEST(MapsTest,parse_name)246*eb293b8fSAndroid Build Coastguard Worker TEST(MapsTest, parse_name) {
247*eb293b8fSAndroid Build Coastguard Worker   BufferMaps maps(
248*eb293b8fSAndroid Build Coastguard Worker       "7b29b000-7b29e000 rw-p 00000000 00:00 0\n"
249*eb293b8fSAndroid Build Coastguard Worker       "7b29e000-7b29f000 rw-p 00000000 00:00 0 /system/lib/fake.so\n"
250*eb293b8fSAndroid Build Coastguard Worker       "7b29f000-7b2a0000 rw-p 00000000 00:00 0");
251*eb293b8fSAndroid Build Coastguard Worker 
252*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(maps.Parse());
253*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(3U, maps.Total());
254*eb293b8fSAndroid Build Coastguard Worker 
255*eb293b8fSAndroid Build Coastguard Worker   auto info = maps.Get(0);
256*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(info != nullptr);
257*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ("", info->name());
258*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0x7b29b000U, info->start());
259*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0x7b29e000U, info->end());
260*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0U, info->offset());
261*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(PROT_READ | PROT_WRITE, info->flags());
262*eb293b8fSAndroid Build Coastguard Worker 
263*eb293b8fSAndroid Build Coastguard Worker   info = maps.Get(1);
264*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(info != nullptr);
265*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ("/system/lib/fake.so", info->name());
266*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0x7b29e000U, info->start());
267*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0x7b29f000U, info->end());
268*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0U, info->offset());
269*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(PROT_READ | PROT_WRITE, info->flags());
270*eb293b8fSAndroid Build Coastguard Worker 
271*eb293b8fSAndroid Build Coastguard Worker   info = maps.Get(2);
272*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(info != nullptr);
273*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ("", info->name());
274*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0x7b29f000U, info->start());
275*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0x7b2a0000U, info->end());
276*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0U, info->offset());
277*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(PROT_READ | PROT_WRITE, info->flags());
278*eb293b8fSAndroid Build Coastguard Worker 
279*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(maps.Get(3) == nullptr);
280*eb293b8fSAndroid Build Coastguard Worker }
281*eb293b8fSAndroid Build Coastguard Worker 
TEST(MapsTest,parse_offset)282*eb293b8fSAndroid Build Coastguard Worker TEST(MapsTest, parse_offset) {
283*eb293b8fSAndroid Build Coastguard Worker   BufferMaps maps(
284*eb293b8fSAndroid Build Coastguard Worker       "a000-e000 rw-p 00000000 00:00 0 /system/lib/fake.so\n"
285*eb293b8fSAndroid Build Coastguard Worker       "e000-f000 rw-p 00a12345 00:00 0 /system/lib/fake.so\n");
286*eb293b8fSAndroid Build Coastguard Worker 
287*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(maps.Parse());
288*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(2U, maps.Total());
289*eb293b8fSAndroid Build Coastguard Worker 
290*eb293b8fSAndroid Build Coastguard Worker   auto info = maps.Get(0);
291*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(info != nullptr);
292*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0U, info->offset());
293*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0xa000U, info->start());
294*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0xe000U, info->end());
295*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(PROT_READ | PROT_WRITE, info->flags());
296*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ("/system/lib/fake.so", info->name());
297*eb293b8fSAndroid Build Coastguard Worker 
298*eb293b8fSAndroid Build Coastguard Worker   info = maps.Get(1);
299*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(info != nullptr);
300*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0xa12345U, info->offset());
301*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0xe000U, info->start());
302*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0xf000U, info->end());
303*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(PROT_READ | PROT_WRITE, info->flags());
304*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ("/system/lib/fake.so", info->name());
305*eb293b8fSAndroid Build Coastguard Worker 
306*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(maps.Get(2) == nullptr);
307*eb293b8fSAndroid Build Coastguard Worker }
308*eb293b8fSAndroid Build Coastguard Worker 
TEST(MapsTest,iterate)309*eb293b8fSAndroid Build Coastguard Worker TEST(MapsTest, iterate) {
310*eb293b8fSAndroid Build Coastguard Worker   BufferMaps maps(
311*eb293b8fSAndroid Build Coastguard Worker       "a000-e000 rw-p 00000000 00:00 0 /system/lib/fake.so\n"
312*eb293b8fSAndroid Build Coastguard Worker       "e000-f000 rw-p 00a12345 00:00 0 /system/lib/fake.so\n");
313*eb293b8fSAndroid Build Coastguard Worker 
314*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(maps.Parse());
315*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(2U, maps.Total());
316*eb293b8fSAndroid Build Coastguard Worker 
317*eb293b8fSAndroid Build Coastguard Worker   Maps::iterator it = maps.begin();
318*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0xa000U, (*it)->start());
319*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0xe000U, (*it)->end());
320*eb293b8fSAndroid Build Coastguard Worker   ++it;
321*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0xe000U, (*it)->start());
322*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0xf000U, (*it)->end());
323*eb293b8fSAndroid Build Coastguard Worker   ++it;
324*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(maps.end(), it);
325*eb293b8fSAndroid Build Coastguard Worker }
326*eb293b8fSAndroid Build Coastguard Worker 
TEST(MapsTest,const_iterate)327*eb293b8fSAndroid Build Coastguard Worker TEST(MapsTest, const_iterate) {
328*eb293b8fSAndroid Build Coastguard Worker   BufferMaps maps(
329*eb293b8fSAndroid Build Coastguard Worker       "a000-e000 rw-p 00000000 00:00 0 /system/lib/fake.so\n"
330*eb293b8fSAndroid Build Coastguard Worker       "e000-f000 rw-p 00a12345 00:00 0 /system/lib/fake.so\n");
331*eb293b8fSAndroid Build Coastguard Worker 
332*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(maps.Parse());
333*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(2U, maps.Total());
334*eb293b8fSAndroid Build Coastguard Worker 
335*eb293b8fSAndroid Build Coastguard Worker   Maps::const_iterator it = maps.begin();
336*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0xa000U, (*it)->start());
337*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0xe000U, (*it)->end());
338*eb293b8fSAndroid Build Coastguard Worker   ++it;
339*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0xe000U, (*it)->start());
340*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0xf000U, (*it)->end());
341*eb293b8fSAndroid Build Coastguard Worker   ++it;
342*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(maps.end(), it);
343*eb293b8fSAndroid Build Coastguard Worker }
344*eb293b8fSAndroid Build Coastguard Worker 
TEST(MapsTest,device)345*eb293b8fSAndroid Build Coastguard Worker TEST(MapsTest, device) {
346*eb293b8fSAndroid Build Coastguard Worker   BufferMaps maps(
347*eb293b8fSAndroid Build Coastguard Worker       "a000-e000 rw-p 00000000 00:00 0 /dev/\n"
348*eb293b8fSAndroid Build Coastguard Worker       "f000-f100 rw-p 00000000 00:00 0 /dev/does_not_exist\n"
349*eb293b8fSAndroid Build Coastguard Worker       "f100-f200 rw-p 00000000 00:00 0 /dev/ashmem/does_not_exist\n"
350*eb293b8fSAndroid Build Coastguard Worker       "f200-f300 rw-p 00000000 00:00 0 /devsomething/does_not_exist\n");
351*eb293b8fSAndroid Build Coastguard Worker 
352*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(maps.Parse());
353*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(4U, maps.Total());
354*eb293b8fSAndroid Build Coastguard Worker 
355*eb293b8fSAndroid Build Coastguard Worker   auto info = maps.Get(0);
356*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(info != nullptr);
357*eb293b8fSAndroid Build Coastguard Worker   EXPECT_TRUE(info->flags() & 0x8000);
358*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ("/dev/", info->name());
359*eb293b8fSAndroid Build Coastguard Worker 
360*eb293b8fSAndroid Build Coastguard Worker   info = maps.Get(1);
361*eb293b8fSAndroid Build Coastguard Worker   EXPECT_TRUE(info->flags() & 0x8000);
362*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ("/dev/does_not_exist", info->name());
363*eb293b8fSAndroid Build Coastguard Worker 
364*eb293b8fSAndroid Build Coastguard Worker   info = maps.Get(2);
365*eb293b8fSAndroid Build Coastguard Worker   EXPECT_FALSE(info->flags() & 0x8000);
366*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ("/dev/ashmem/does_not_exist", info->name());
367*eb293b8fSAndroid Build Coastguard Worker 
368*eb293b8fSAndroid Build Coastguard Worker   info = maps.Get(3);
369*eb293b8fSAndroid Build Coastguard Worker   EXPECT_FALSE(info->flags() & 0x8000);
370*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ("/devsomething/does_not_exist", info->name());
371*eb293b8fSAndroid Build Coastguard Worker }
372*eb293b8fSAndroid Build Coastguard Worker 
TEST(MapsTest,file_smoke)373*eb293b8fSAndroid Build Coastguard Worker TEST(MapsTest, file_smoke) {
374*eb293b8fSAndroid Build Coastguard Worker   TemporaryFile tf;
375*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(tf.fd != -1);
376*eb293b8fSAndroid Build Coastguard Worker 
377*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(
378*eb293b8fSAndroid Build Coastguard Worker       android::base::WriteStringToFile("7b29b000-7b29e000 r-xp a0000000 00:00 0   /fake.so\n"
379*eb293b8fSAndroid Build Coastguard Worker                                        "7b2b0000-7b2e0000 r-xp b0000000 00:00 0   /fake2.so\n"
380*eb293b8fSAndroid Build Coastguard Worker                                        "7b2e0000-7b2f0000 r-xp c0000000 00:00 0   /fake3.so\n",
381*eb293b8fSAndroid Build Coastguard Worker                                        tf.path, 0660, getuid(), getgid()));
382*eb293b8fSAndroid Build Coastguard Worker 
383*eb293b8fSAndroid Build Coastguard Worker   FileMaps maps(tf.path);
384*eb293b8fSAndroid Build Coastguard Worker 
385*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(maps.Parse());
386*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(3U, maps.Total());
387*eb293b8fSAndroid Build Coastguard Worker 
388*eb293b8fSAndroid Build Coastguard Worker   auto info = maps.Get(0);
389*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(info != nullptr);
390*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0x7b29b000U, info->start());
391*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0x7b29e000U, info->end());
392*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0xa0000000U, info->offset());
393*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(PROT_READ | PROT_EXEC, info->flags());
394*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ("/fake.so", info->name());
395*eb293b8fSAndroid Build Coastguard Worker 
396*eb293b8fSAndroid Build Coastguard Worker   info = maps.Get(1);
397*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(info != nullptr);
398*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0x7b2b0000U, info->start());
399*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0x7b2e0000U, info->end());
400*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0xb0000000U, info->offset());
401*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(PROT_READ | PROT_EXEC, info->flags());
402*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ("/fake2.so", info->name());
403*eb293b8fSAndroid Build Coastguard Worker 
404*eb293b8fSAndroid Build Coastguard Worker   info = maps.Get(2);
405*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(info != nullptr);
406*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0x7b2e0000U, info->start());
407*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0x7b2f0000U, info->end());
408*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0xc0000000U, info->offset());
409*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(PROT_READ | PROT_EXEC, info->flags());
410*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ("/fake3.so", info->name());
411*eb293b8fSAndroid Build Coastguard Worker 
412*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(maps.Get(3) == nullptr);
413*eb293b8fSAndroid Build Coastguard Worker }
414*eb293b8fSAndroid Build Coastguard Worker 
TEST(MapsTest,file_no_map_name)415*eb293b8fSAndroid Build Coastguard Worker TEST(MapsTest, file_no_map_name) {
416*eb293b8fSAndroid Build Coastguard Worker   TemporaryFile tf;
417*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(tf.fd != -1);
418*eb293b8fSAndroid Build Coastguard Worker 
419*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(
420*eb293b8fSAndroid Build Coastguard Worker       android::base::WriteStringToFile("7b29b000-7b29e000 r-xp a0000000 00:00 0\n"
421*eb293b8fSAndroid Build Coastguard Worker                                        "7b2b0000-7b2e0000 r-xp b0000000 00:00 0   /fake2.so\n"
422*eb293b8fSAndroid Build Coastguard Worker                                        "7b2e0000-7b2f0000 r-xp c0000000 00:00 0 \n",
423*eb293b8fSAndroid Build Coastguard Worker                                        tf.path, 0660, getuid(), getgid()));
424*eb293b8fSAndroid Build Coastguard Worker 
425*eb293b8fSAndroid Build Coastguard Worker   FileMaps maps(tf.path);
426*eb293b8fSAndroid Build Coastguard Worker 
427*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(maps.Parse());
428*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(3U, maps.Total());
429*eb293b8fSAndroid Build Coastguard Worker 
430*eb293b8fSAndroid Build Coastguard Worker   auto info = maps.Get(0);
431*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(info != nullptr);
432*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0x7b29b000U, info->start());
433*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0x7b29e000U, info->end());
434*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0xa0000000U, info->offset());
435*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(PROT_READ | PROT_EXEC, info->flags());
436*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ("", info->name());
437*eb293b8fSAndroid Build Coastguard Worker 
438*eb293b8fSAndroid Build Coastguard Worker   info = maps.Get(1);
439*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(info != nullptr);
440*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0x7b2b0000U, info->start());
441*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0x7b2e0000U, info->end());
442*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0xb0000000U, info->offset());
443*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(PROT_READ | PROT_EXEC, info->flags());
444*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ("/fake2.so", info->name());
445*eb293b8fSAndroid Build Coastguard Worker 
446*eb293b8fSAndroid Build Coastguard Worker   info = maps.Get(2);
447*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(info != nullptr);
448*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0x7b2e0000U, info->start());
449*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0x7b2f0000U, info->end());
450*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0xc0000000U, info->offset());
451*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(PROT_READ | PROT_EXEC, info->flags());
452*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ("", info->name());
453*eb293b8fSAndroid Build Coastguard Worker 
454*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(maps.Get(3) == nullptr);
455*eb293b8fSAndroid Build Coastguard Worker }
456*eb293b8fSAndroid Build Coastguard Worker 
457*eb293b8fSAndroid Build Coastguard Worker // Verify that a file that crosses a buffer is parsed correctly.
CreateEntry(size_t index)458*eb293b8fSAndroid Build Coastguard Worker static std::string CreateEntry(size_t index) {
459*eb293b8fSAndroid Build Coastguard Worker   return android::base::StringPrintf("%08zx-%08zx rwxp 0000 00:00 0\n", index * 4096,
460*eb293b8fSAndroid Build Coastguard Worker                                      (index + 1) * 4096);
461*eb293b8fSAndroid Build Coastguard Worker }
462*eb293b8fSAndroid Build Coastguard Worker 
TEST(MapsTest,file_buffer_cross)463*eb293b8fSAndroid Build Coastguard Worker TEST(MapsTest, file_buffer_cross) {
464*eb293b8fSAndroid Build Coastguard Worker   constexpr size_t kBufferSize = 2048;
465*eb293b8fSAndroid Build Coastguard Worker   TemporaryFile tf;
466*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(tf.fd != -1);
467*eb293b8fSAndroid Build Coastguard Worker 
468*eb293b8fSAndroid Build Coastguard Worker   // Compute how many to add in the first buffer.
469*eb293b8fSAndroid Build Coastguard Worker   size_t entry_len = CreateEntry(0).size();
470*eb293b8fSAndroid Build Coastguard Worker   size_t index;
471*eb293b8fSAndroid Build Coastguard Worker   std::string file_data;
472*eb293b8fSAndroid Build Coastguard Worker   for (index = 0; index < kBufferSize / entry_len; index++) {
473*eb293b8fSAndroid Build Coastguard Worker     file_data += CreateEntry(index);
474*eb293b8fSAndroid Build Coastguard Worker   }
475*eb293b8fSAndroid Build Coastguard Worker   // Add a long name to make sure that the first buffer does not contain a
476*eb293b8fSAndroid Build Coastguard Worker   // complete line.
477*eb293b8fSAndroid Build Coastguard Worker   // Remove the last newline.
478*eb293b8fSAndroid Build Coastguard Worker   size_t extra = 0;
479*eb293b8fSAndroid Build Coastguard Worker   size_t leftover = kBufferSize % entry_len;
480*eb293b8fSAndroid Build Coastguard Worker   size_t overlap1_index = 0;
481*eb293b8fSAndroid Build Coastguard Worker   std::string overlap1_name;
482*eb293b8fSAndroid Build Coastguard Worker   if (leftover == 0) {
483*eb293b8fSAndroid Build Coastguard Worker     // Exact match, add a long name to cross over the value.
484*eb293b8fSAndroid Build Coastguard Worker     overlap1_name = "/fake/name/is/long/on/purpose";
485*eb293b8fSAndroid Build Coastguard Worker     file_data.erase(file_data.size() - 1);
486*eb293b8fSAndroid Build Coastguard Worker     file_data += ' ' + overlap1_name + '\n';
487*eb293b8fSAndroid Build Coastguard Worker     extra = entry_len + overlap1_name.size() + 1;
488*eb293b8fSAndroid Build Coastguard Worker     overlap1_index = index;
489*eb293b8fSAndroid Build Coastguard Worker   }
490*eb293b8fSAndroid Build Coastguard Worker 
491*eb293b8fSAndroid Build Coastguard Worker   // Compute how many need to go in to hit the buffer boundary exactly.
492*eb293b8fSAndroid Build Coastguard Worker   size_t bytes_left_in_buffer = kBufferSize - extra;
493*eb293b8fSAndroid Build Coastguard Worker   size_t entries_to_add = bytes_left_in_buffer / entry_len + index;
494*eb293b8fSAndroid Build Coastguard Worker   for (; index < entries_to_add; index++) {
495*eb293b8fSAndroid Build Coastguard Worker     file_data += CreateEntry(index);
496*eb293b8fSAndroid Build Coastguard Worker   }
497*eb293b8fSAndroid Build Coastguard Worker 
498*eb293b8fSAndroid Build Coastguard Worker   // Now figure out how many bytes to add to get exactly to the buffer boundary.
499*eb293b8fSAndroid Build Coastguard Worker   leftover = bytes_left_in_buffer % entry_len;
500*eb293b8fSAndroid Build Coastguard Worker   std::string overlap2_name;
501*eb293b8fSAndroid Build Coastguard Worker   size_t overlap2_index = 0;
502*eb293b8fSAndroid Build Coastguard Worker   if (leftover != 0) {
503*eb293b8fSAndroid Build Coastguard Worker     file_data.erase(file_data.size() - 1);
504*eb293b8fSAndroid Build Coastguard Worker     file_data += ' ';
505*eb293b8fSAndroid Build Coastguard Worker     overlap2_name = std::string(leftover - 1, 'x');
506*eb293b8fSAndroid Build Coastguard Worker     file_data += overlap2_name + '\n';
507*eb293b8fSAndroid Build Coastguard Worker     overlap2_index = index - 1;
508*eb293b8fSAndroid Build Coastguard Worker   }
509*eb293b8fSAndroid Build Coastguard Worker 
510*eb293b8fSAndroid Build Coastguard Worker   // Now add a few entries on the next page.
511*eb293b8fSAndroid Build Coastguard Worker   for (size_t start = index; index < start + 10; index++) {
512*eb293b8fSAndroid Build Coastguard Worker     file_data += CreateEntry(index);
513*eb293b8fSAndroid Build Coastguard Worker   }
514*eb293b8fSAndroid Build Coastguard Worker 
515*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(android::base::WriteStringToFile(file_data, tf.path, 0660, getuid(), getgid()));
516*eb293b8fSAndroid Build Coastguard Worker 
517*eb293b8fSAndroid Build Coastguard Worker   FileMaps maps(tf.path);
518*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(maps.Parse());
519*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(index, maps.Total());
520*eb293b8fSAndroid Build Coastguard Worker   // Verify all of the maps.
521*eb293b8fSAndroid Build Coastguard Worker   for (size_t i = 0; i < index; i++) {
522*eb293b8fSAndroid Build Coastguard Worker     auto info = maps.Get(i);
523*eb293b8fSAndroid Build Coastguard Worker     ASSERT_TRUE(info != nullptr) << "Failed verifying index " + std::to_string(i);
524*eb293b8fSAndroid Build Coastguard Worker     EXPECT_EQ(i * 4096, info->start()) << "Failed verifying index " + std::to_string(i);
525*eb293b8fSAndroid Build Coastguard Worker     EXPECT_EQ((i + 1) * 4096, info->end()) << "Failed verifying index " + std::to_string(i);
526*eb293b8fSAndroid Build Coastguard Worker     EXPECT_EQ(0U, info->offset()) << "Failed verifying index " + std::to_string(i);
527*eb293b8fSAndroid Build Coastguard Worker     if (overlap1_index != 0 && i == overlap1_index) {
528*eb293b8fSAndroid Build Coastguard Worker       EXPECT_EQ(overlap1_name, info->name())
529*eb293b8fSAndroid Build Coastguard Worker           << "Failed verifying overlap1 name " + std::to_string(i);
530*eb293b8fSAndroid Build Coastguard Worker     } else if (overlap2_index != 0 && i == overlap2_index) {
531*eb293b8fSAndroid Build Coastguard Worker       EXPECT_EQ(overlap2_name, info->name())
532*eb293b8fSAndroid Build Coastguard Worker           << "Failed verifying overlap2 name " + std::to_string(i);
533*eb293b8fSAndroid Build Coastguard Worker     } else {
534*eb293b8fSAndroid Build Coastguard Worker       EXPECT_EQ("", info->name()) << "Failed verifying index " + std::to_string(i);
535*eb293b8fSAndroid Build Coastguard Worker     }
536*eb293b8fSAndroid Build Coastguard Worker   }
537*eb293b8fSAndroid Build Coastguard Worker }
538*eb293b8fSAndroid Build Coastguard Worker 
TEST(MapsTest,file_should_fail)539*eb293b8fSAndroid Build Coastguard Worker TEST(MapsTest, file_should_fail) {
540*eb293b8fSAndroid Build Coastguard Worker   TemporaryFile tf;
541*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(tf.fd != -1);
542*eb293b8fSAndroid Build Coastguard Worker 
543*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(android::base::WriteStringToFile(
544*eb293b8fSAndroid Build Coastguard Worker       "7ffff7dda000-7ffff7dfd7ffff7ff3000-7ffff7ff4000 ---p 0000f000 fc:02 44171565\n", tf.path,
545*eb293b8fSAndroid Build Coastguard Worker       0660, getuid(), getgid()));
546*eb293b8fSAndroid Build Coastguard Worker 
547*eb293b8fSAndroid Build Coastguard Worker   FileMaps maps(tf.path);
548*eb293b8fSAndroid Build Coastguard Worker 
549*eb293b8fSAndroid Build Coastguard Worker   ASSERT_FALSE(maps.Parse());
550*eb293b8fSAndroid Build Coastguard Worker }
551*eb293b8fSAndroid Build Coastguard Worker 
552*eb293b8fSAndroid Build Coastguard Worker // Create a maps file that is extremely large.
TEST(MapsTest,large_file)553*eb293b8fSAndroid Build Coastguard Worker TEST(MapsTest, large_file) {
554*eb293b8fSAndroid Build Coastguard Worker   TemporaryFile tf;
555*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(tf.fd != -1);
556*eb293b8fSAndroid Build Coastguard Worker 
557*eb293b8fSAndroid Build Coastguard Worker   std::string file_data;
558*eb293b8fSAndroid Build Coastguard Worker   uint64_t start = 0x700000;
559*eb293b8fSAndroid Build Coastguard Worker   for (size_t i = 0; i < 5000; i++) {
560*eb293b8fSAndroid Build Coastguard Worker     file_data +=
561*eb293b8fSAndroid Build Coastguard Worker         android::base::StringPrintf("%" PRIx64 "-%" PRIx64 " r-xp 1000 00:0 0 /fake%zu.so\n",
562*eb293b8fSAndroid Build Coastguard Worker                                     start + i * 4096, start + (i + 1) * 4096, i);
563*eb293b8fSAndroid Build Coastguard Worker   }
564*eb293b8fSAndroid Build Coastguard Worker 
565*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(android::base::WriteStringToFile(file_data, tf.path, 0660, getuid(), getgid()));
566*eb293b8fSAndroid Build Coastguard Worker 
567*eb293b8fSAndroid Build Coastguard Worker   FileMaps maps(tf.path);
568*eb293b8fSAndroid Build Coastguard Worker 
569*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(maps.Parse());
570*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(5000U, maps.Total());
571*eb293b8fSAndroid Build Coastguard Worker   for (size_t i = 0; i < 5000; i++) {
572*eb293b8fSAndroid Build Coastguard Worker     auto info = maps.Get(i);
573*eb293b8fSAndroid Build Coastguard Worker     EXPECT_EQ(start + i * 4096, info->start()) << "Failed at map " + std::to_string(i);
574*eb293b8fSAndroid Build Coastguard Worker     EXPECT_EQ(start + (i + 1) * 4096, info->end()) << "Failed at map " + std::to_string(i);
575*eb293b8fSAndroid Build Coastguard Worker     std::string name = "/fake" + std::to_string(i) + ".so";
576*eb293b8fSAndroid Build Coastguard Worker     EXPECT_EQ(name, info->name()) << "Failed at map " + std::to_string(i);
577*eb293b8fSAndroid Build Coastguard Worker   }
578*eb293b8fSAndroid Build Coastguard Worker }
579*eb293b8fSAndroid Build Coastguard Worker 
TEST(MapsTest,find)580*eb293b8fSAndroid Build Coastguard Worker TEST(MapsTest, find) {
581*eb293b8fSAndroid Build Coastguard Worker   BufferMaps maps(
582*eb293b8fSAndroid Build Coastguard Worker       "1000-2000 r--p 00000010 00:00 0 /system/lib/fake1.so\n"
583*eb293b8fSAndroid Build Coastguard Worker       "3000-4000 -w-p 00000020 00:00 0 /system/lib/fake2.so\n"
584*eb293b8fSAndroid Build Coastguard Worker       "6000-8000 --xp 00000030 00:00 0 /system/lib/fake3.so\n"
585*eb293b8fSAndroid Build Coastguard Worker       "a000-b000 rw-p 00000040 00:00 0 /system/lib/fake4.so\n"
586*eb293b8fSAndroid Build Coastguard Worker       "e000-f000 rwxp 00000050 00:00 0 /system/lib/fake5.so\n");
587*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(maps.Parse());
588*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(5U, maps.Total());
589*eb293b8fSAndroid Build Coastguard Worker 
590*eb293b8fSAndroid Build Coastguard Worker   EXPECT_TRUE(maps.Find(0x500) == nullptr);
591*eb293b8fSAndroid Build Coastguard Worker   EXPECT_TRUE(maps.Find(0x2000) == nullptr);
592*eb293b8fSAndroid Build Coastguard Worker   EXPECT_TRUE(maps.Find(0x5010) == nullptr);
593*eb293b8fSAndroid Build Coastguard Worker   EXPECT_TRUE(maps.Find(0x9a00) == nullptr);
594*eb293b8fSAndroid Build Coastguard Worker   EXPECT_TRUE(maps.Find(0xf000) == nullptr);
595*eb293b8fSAndroid Build Coastguard Worker   EXPECT_TRUE(maps.Find(0xf010) == nullptr);
596*eb293b8fSAndroid Build Coastguard Worker 
597*eb293b8fSAndroid Build Coastguard Worker   auto info = maps.Find(0x1000);
598*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(info != nullptr);
599*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0x1000U, info->start());
600*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0x2000U, info->end());
601*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0x10U, info->offset());
602*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(PROT_READ, info->flags());
603*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ("/system/lib/fake1.so", info->name());
604*eb293b8fSAndroid Build Coastguard Worker 
605*eb293b8fSAndroid Build Coastguard Worker   info = maps.Find(0x3020);
606*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(info != nullptr);
607*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0x3000U, info->start());
608*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0x4000U, info->end());
609*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0x20U, info->offset());
610*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(PROT_WRITE, info->flags());
611*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ("/system/lib/fake2.so", info->name());
612*eb293b8fSAndroid Build Coastguard Worker 
613*eb293b8fSAndroid Build Coastguard Worker   info = maps.Find(0x6020);
614*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(info != nullptr);
615*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0x6000U, info->start());
616*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0x8000U, info->end());
617*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0x30U, info->offset());
618*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(PROT_EXEC, info->flags());
619*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ("/system/lib/fake3.so", info->name());
620*eb293b8fSAndroid Build Coastguard Worker 
621*eb293b8fSAndroid Build Coastguard Worker   info = maps.Find(0xafff);
622*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(info != nullptr);
623*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0xa000U, info->start());
624*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0xb000U, info->end());
625*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0x40U, info->offset());
626*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(PROT_READ | PROT_WRITE, info->flags());
627*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ("/system/lib/fake4.so", info->name());
628*eb293b8fSAndroid Build Coastguard Worker 
629*eb293b8fSAndroid Build Coastguard Worker   info = maps.Find(0xe500);
630*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(info != nullptr);
631*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0xe000U, info->start());
632*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0xf000U, info->end());
633*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0x50U, info->offset());
634*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(PROT_READ | PROT_WRITE | PROT_EXEC, info->flags());
635*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ("/system/lib/fake5.so", info->name());
636*eb293b8fSAndroid Build Coastguard Worker }
637*eb293b8fSAndroid Build Coastguard Worker 
TEST(MapsTest,sort)638*eb293b8fSAndroid Build Coastguard Worker TEST(MapsTest, sort) {
639*eb293b8fSAndroid Build Coastguard Worker   Maps maps;
640*eb293b8fSAndroid Build Coastguard Worker 
641*eb293b8fSAndroid Build Coastguard Worker   maps.Add(0x8000, 0x9000, 0, 0, "", 0);
642*eb293b8fSAndroid Build Coastguard Worker   maps.Add(0x7000, 0x8000, 0, 0, "lib.so", 0);
643*eb293b8fSAndroid Build Coastguard Worker   maps.Add(0x6000, 0x7000, 0, 0, "", 0);
644*eb293b8fSAndroid Build Coastguard Worker   maps.Add(0x5000, 0x6000, 0, 0, "lib.so", 0);
645*eb293b8fSAndroid Build Coastguard Worker   maps.Add(0x4000, 0x5000, 0, 0, "", 0);
646*eb293b8fSAndroid Build Coastguard Worker   maps.Add(0x3000, 0x4000, 0, 0, "", 0);
647*eb293b8fSAndroid Build Coastguard Worker   maps.Add(0x2000, 0x3000, 0, 0, "lib.so", 0);
648*eb293b8fSAndroid Build Coastguard Worker   maps.Add(0x1000, 0x2000, 0, 0, "", 0);
649*eb293b8fSAndroid Build Coastguard Worker 
650*eb293b8fSAndroid Build Coastguard Worker   maps.Sort();
651*eb293b8fSAndroid Build Coastguard Worker 
652*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0x1000UL, maps.Get(0)->start());
653*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(nullptr, maps.Get(0)->prev_map());
654*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(maps.Get(1), maps.Get(0)->next_map());
655*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(nullptr, maps.Get(0)->GetPrevRealMap());
656*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(nullptr, maps.Get(0)->GetNextRealMap());
657*eb293b8fSAndroid Build Coastguard Worker 
658*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0x2000UL, maps.Get(1)->start());
659*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(maps.Get(0), maps.Get(1)->prev_map());
660*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(maps.Get(2), maps.Get(1)->next_map());
661*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(nullptr, maps.Get(1)->GetPrevRealMap());
662*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(maps.Get(4), maps.Get(1)->GetNextRealMap());
663*eb293b8fSAndroid Build Coastguard Worker 
664*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0x3000UL, maps.Get(2)->start());
665*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(maps.Get(1), maps.Get(2)->prev_map());
666*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(maps.Get(3), maps.Get(2)->next_map());
667*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(nullptr, maps.Get(2)->GetPrevRealMap());
668*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(nullptr, maps.Get(2)->GetNextRealMap());
669*eb293b8fSAndroid Build Coastguard Worker 
670*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0x4000UL, maps.Get(3)->start());
671*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(maps.Get(2), maps.Get(3)->prev_map());
672*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(maps.Get(4), maps.Get(3)->next_map());
673*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(nullptr, maps.Get(3)->GetPrevRealMap());
674*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(nullptr, maps.Get(3)->GetNextRealMap());
675*eb293b8fSAndroid Build Coastguard Worker 
676*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0x5000UL, maps.Get(4)->start());
677*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(maps.Get(3), maps.Get(4)->prev_map());
678*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(maps.Get(5), maps.Get(4)->next_map());
679*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(maps.Get(1), maps.Get(4)->GetPrevRealMap());
680*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(maps.Get(6), maps.Get(4)->GetNextRealMap());
681*eb293b8fSAndroid Build Coastguard Worker 
682*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0x6000UL, maps.Get(5)->start());
683*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(maps.Get(4), maps.Get(5)->prev_map());
684*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(maps.Get(6), maps.Get(5)->next_map());
685*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(nullptr, maps.Get(5)->GetPrevRealMap());
686*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(nullptr, maps.Get(5)->GetNextRealMap());
687*eb293b8fSAndroid Build Coastguard Worker 
688*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0x7000UL, maps.Get(6)->start());
689*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(maps.Get(5), maps.Get(6)->prev_map());
690*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(maps.Get(7), maps.Get(6)->next_map());
691*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(maps.Get(4), maps.Get(6)->GetPrevRealMap());
692*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(nullptr, maps.Get(6)->GetNextRealMap());
693*eb293b8fSAndroid Build Coastguard Worker 
694*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0x8000UL, maps.Get(7)->start());
695*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(maps.Get(6), maps.Get(7)->prev_map());
696*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(nullptr, maps.Get(7)->next_map());
697*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(nullptr, maps.Get(7)->GetPrevRealMap());
698*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(nullptr, maps.Get(7)->GetNextRealMap());
699*eb293b8fSAndroid Build Coastguard Worker }
700*eb293b8fSAndroid Build Coastguard Worker 
TEST(MapsTest,sort_empty)701*eb293b8fSAndroid Build Coastguard Worker TEST(MapsTest, sort_empty) {
702*eb293b8fSAndroid Build Coastguard Worker   Maps maps;
703*eb293b8fSAndroid Build Coastguard Worker 
704*eb293b8fSAndroid Build Coastguard Worker   maps.Sort();
705*eb293b8fSAndroid Build Coastguard Worker 
706*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0ULL, maps.Total());
707*eb293b8fSAndroid Build Coastguard Worker }
708*eb293b8fSAndroid Build Coastguard Worker 
709*eb293b8fSAndroid Build Coastguard Worker }  // namespace unwindstack
710