1*eb293b8fSAndroid Build Coastguard Worker /*
2*eb293b8fSAndroid Build Coastguard Worker * Copyright (C) 2019 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 <stdint.h>
18*eb293b8fSAndroid Build Coastguard Worker #include <sys/mman.h>
19*eb293b8fSAndroid Build Coastguard Worker
20*eb293b8fSAndroid Build Coastguard Worker #include <string>
21*eb293b8fSAndroid Build Coastguard Worker #include <vector>
22*eb293b8fSAndroid Build Coastguard Worker
23*eb293b8fSAndroid Build Coastguard Worker #include <gtest/gtest.h>
24*eb293b8fSAndroid Build Coastguard Worker
25*eb293b8fSAndroid Build Coastguard Worker #include <android-base/file.h>
26*eb293b8fSAndroid Build Coastguard Worker #include <unwindstack/Maps.h>
27*eb293b8fSAndroid Build Coastguard Worker
28*eb293b8fSAndroid Build Coastguard Worker namespace unwindstack {
29*eb293b8fSAndroid Build Coastguard Worker
30*eb293b8fSAndroid Build Coastguard Worker class TestUpdatableMaps : public LocalUpdatableMaps {
31*eb293b8fSAndroid Build Coastguard Worker public:
TestUpdatableMaps()32*eb293b8fSAndroid Build Coastguard Worker TestUpdatableMaps() : LocalUpdatableMaps() {}
33*eb293b8fSAndroid Build Coastguard Worker virtual ~TestUpdatableMaps() = default;
34*eb293b8fSAndroid Build Coastguard Worker
GetMapsFile() const35*eb293b8fSAndroid Build Coastguard Worker const std::string GetMapsFile() const override { return maps_file_; }
36*eb293b8fSAndroid Build Coastguard Worker
TestSetMapsFile(const std::string & maps_file)37*eb293b8fSAndroid Build Coastguard Worker void TestSetMapsFile(const std::string& maps_file) { maps_file_ = maps_file; }
38*eb293b8fSAndroid Build Coastguard Worker
39*eb293b8fSAndroid Build Coastguard Worker private:
40*eb293b8fSAndroid Build Coastguard Worker std::string maps_file_;
41*eb293b8fSAndroid Build Coastguard Worker };
42*eb293b8fSAndroid Build Coastguard Worker
43*eb293b8fSAndroid Build Coastguard Worker class LocalUpdatableMapsTest : public ::testing::Test {
44*eb293b8fSAndroid Build Coastguard Worker protected:
GetDefaultMapString()45*eb293b8fSAndroid Build Coastguard Worker static const std::string GetDefaultMapString() {
46*eb293b8fSAndroid Build Coastguard Worker return "3000-4000 r-xp 00000 00:00 0\n8000-9000 r-xp 00000 00:00 0\n";
47*eb293b8fSAndroid Build Coastguard Worker }
48*eb293b8fSAndroid Build Coastguard Worker
SetUp()49*eb293b8fSAndroid Build Coastguard Worker void SetUp() override {
50*eb293b8fSAndroid Build Coastguard Worker TemporaryFile tf;
51*eb293b8fSAndroid Build Coastguard Worker ASSERT_TRUE(android::base::WriteStringToFile(GetDefaultMapString(), tf.path));
52*eb293b8fSAndroid Build Coastguard Worker
53*eb293b8fSAndroid Build Coastguard Worker maps_.TestSetMapsFile(tf.path);
54*eb293b8fSAndroid Build Coastguard Worker ASSERT_TRUE(maps_.Parse());
55*eb293b8fSAndroid Build Coastguard Worker ASSERT_EQ(2U, maps_.Total());
56*eb293b8fSAndroid Build Coastguard Worker
57*eb293b8fSAndroid Build Coastguard Worker auto map_info = maps_.Get(0);
58*eb293b8fSAndroid Build Coastguard Worker ASSERT_TRUE(map_info != nullptr);
59*eb293b8fSAndroid Build Coastguard Worker EXPECT_EQ(0x3000U, map_info->start());
60*eb293b8fSAndroid Build Coastguard Worker EXPECT_EQ(0x4000U, map_info->end());
61*eb293b8fSAndroid Build Coastguard Worker EXPECT_EQ(0U, map_info->offset());
62*eb293b8fSAndroid Build Coastguard Worker EXPECT_EQ(PROT_READ | PROT_EXEC, map_info->flags());
63*eb293b8fSAndroid Build Coastguard Worker EXPECT_TRUE(map_info->name().empty());
64*eb293b8fSAndroid Build Coastguard Worker
65*eb293b8fSAndroid Build Coastguard Worker map_info = maps_.Get(1);
66*eb293b8fSAndroid Build Coastguard Worker ASSERT_TRUE(map_info != nullptr);
67*eb293b8fSAndroid Build Coastguard Worker EXPECT_EQ(0x8000U, map_info->start());
68*eb293b8fSAndroid Build Coastguard Worker EXPECT_EQ(0x9000U, map_info->end());
69*eb293b8fSAndroid Build Coastguard Worker EXPECT_EQ(0U, map_info->offset());
70*eb293b8fSAndroid Build Coastguard Worker EXPECT_EQ(PROT_READ | PROT_EXEC, map_info->flags());
71*eb293b8fSAndroid Build Coastguard Worker EXPECT_TRUE(map_info->name().empty());
72*eb293b8fSAndroid Build Coastguard Worker }
73*eb293b8fSAndroid Build Coastguard Worker
74*eb293b8fSAndroid Build Coastguard Worker TestUpdatableMaps maps_;
75*eb293b8fSAndroid Build Coastguard Worker };
76*eb293b8fSAndroid Build Coastguard Worker
TEST_F(LocalUpdatableMapsTest,same_map)77*eb293b8fSAndroid Build Coastguard Worker TEST_F(LocalUpdatableMapsTest, same_map) {
78*eb293b8fSAndroid Build Coastguard Worker TemporaryFile tf;
79*eb293b8fSAndroid Build Coastguard Worker ASSERT_TRUE(android::base::WriteStringToFile(GetDefaultMapString(), tf.path));
80*eb293b8fSAndroid Build Coastguard Worker
81*eb293b8fSAndroid Build Coastguard Worker maps_.TestSetMapsFile(tf.path);
82*eb293b8fSAndroid Build Coastguard Worker ASSERT_TRUE(maps_.Reparse());
83*eb293b8fSAndroid Build Coastguard Worker ASSERT_EQ(2U, maps_.Total());
84*eb293b8fSAndroid Build Coastguard Worker
85*eb293b8fSAndroid Build Coastguard Worker auto map_info = maps_.Get(0);
86*eb293b8fSAndroid Build Coastguard Worker ASSERT_TRUE(map_info != nullptr);
87*eb293b8fSAndroid Build Coastguard Worker EXPECT_EQ(0x3000U, map_info->start());
88*eb293b8fSAndroid Build Coastguard Worker EXPECT_EQ(0x4000U, map_info->end());
89*eb293b8fSAndroid Build Coastguard Worker EXPECT_EQ(0U, map_info->offset());
90*eb293b8fSAndroid Build Coastguard Worker EXPECT_EQ(PROT_READ | PROT_EXEC, map_info->flags());
91*eb293b8fSAndroid Build Coastguard Worker EXPECT_TRUE(map_info->name().empty());
92*eb293b8fSAndroid Build Coastguard Worker EXPECT_EQ(nullptr, map_info->prev_map());
93*eb293b8fSAndroid Build Coastguard Worker EXPECT_EQ(maps_.Get(1), map_info->next_map());
94*eb293b8fSAndroid Build Coastguard Worker
95*eb293b8fSAndroid Build Coastguard Worker map_info = maps_.Get(1);
96*eb293b8fSAndroid Build Coastguard Worker ASSERT_TRUE(map_info != nullptr);
97*eb293b8fSAndroid Build Coastguard Worker EXPECT_EQ(0x8000U, map_info->start());
98*eb293b8fSAndroid Build Coastguard Worker EXPECT_EQ(0x9000U, map_info->end());
99*eb293b8fSAndroid Build Coastguard Worker EXPECT_EQ(0U, map_info->offset());
100*eb293b8fSAndroid Build Coastguard Worker EXPECT_EQ(PROT_READ | PROT_EXEC, map_info->flags());
101*eb293b8fSAndroid Build Coastguard Worker EXPECT_TRUE(map_info->name().empty());
102*eb293b8fSAndroid Build Coastguard Worker EXPECT_EQ(maps_.Get(0), map_info->prev_map());
103*eb293b8fSAndroid Build Coastguard Worker EXPECT_EQ(nullptr, map_info->next_map());
104*eb293b8fSAndroid Build Coastguard Worker }
105*eb293b8fSAndroid Build Coastguard Worker
TEST_F(LocalUpdatableMapsTest,same_map_new_perms)106*eb293b8fSAndroid Build Coastguard Worker TEST_F(LocalUpdatableMapsTest, same_map_new_perms) {
107*eb293b8fSAndroid Build Coastguard Worker TemporaryFile tf;
108*eb293b8fSAndroid Build Coastguard Worker ASSERT_TRUE(
109*eb293b8fSAndroid Build Coastguard Worker android::base::WriteStringToFile("3000-4000 rwxp 00000 00:00 0\n"
110*eb293b8fSAndroid Build Coastguard Worker "8000-9000 r-xp 00000 00:00 0\n",
111*eb293b8fSAndroid Build Coastguard Worker tf.path));
112*eb293b8fSAndroid Build Coastguard Worker
113*eb293b8fSAndroid Build Coastguard Worker maps_.TestSetMapsFile(tf.path);
114*eb293b8fSAndroid Build Coastguard Worker ASSERT_TRUE(maps_.Reparse());
115*eb293b8fSAndroid Build Coastguard Worker ASSERT_EQ(2U, maps_.Total());
116*eb293b8fSAndroid Build Coastguard Worker
117*eb293b8fSAndroid Build Coastguard Worker auto map_info = maps_.Get(0);
118*eb293b8fSAndroid Build Coastguard Worker ASSERT_TRUE(map_info != nullptr);
119*eb293b8fSAndroid Build Coastguard Worker EXPECT_EQ(0x3000U, map_info->start());
120*eb293b8fSAndroid Build Coastguard Worker EXPECT_EQ(0x4000U, map_info->end());
121*eb293b8fSAndroid Build Coastguard Worker EXPECT_EQ(0U, map_info->offset());
122*eb293b8fSAndroid Build Coastguard Worker EXPECT_EQ(PROT_READ | PROT_WRITE | PROT_EXEC, map_info->flags());
123*eb293b8fSAndroid Build Coastguard Worker EXPECT_TRUE(map_info->name().empty());
124*eb293b8fSAndroid Build Coastguard Worker EXPECT_EQ(nullptr, map_info->prev_map());
125*eb293b8fSAndroid Build Coastguard Worker EXPECT_EQ(maps_.Get(1), map_info->next_map());
126*eb293b8fSAndroid Build Coastguard Worker
127*eb293b8fSAndroid Build Coastguard Worker map_info = maps_.Get(1);
128*eb293b8fSAndroid Build Coastguard Worker ASSERT_TRUE(map_info != nullptr);
129*eb293b8fSAndroid Build Coastguard Worker EXPECT_EQ(0x8000U, map_info->start());
130*eb293b8fSAndroid Build Coastguard Worker EXPECT_EQ(0x9000U, map_info->end());
131*eb293b8fSAndroid Build Coastguard Worker EXPECT_EQ(0U, map_info->offset());
132*eb293b8fSAndroid Build Coastguard Worker EXPECT_EQ(PROT_READ | PROT_EXEC, map_info->flags());
133*eb293b8fSAndroid Build Coastguard Worker EXPECT_TRUE(map_info->name().empty());
134*eb293b8fSAndroid Build Coastguard Worker EXPECT_EQ(maps_.Get(0), map_info->prev_map());
135*eb293b8fSAndroid Build Coastguard Worker EXPECT_EQ(nullptr, map_info->next_map());
136*eb293b8fSAndroid Build Coastguard Worker }
137*eb293b8fSAndroid Build Coastguard Worker
TEST_F(LocalUpdatableMapsTest,same_map_new_name)138*eb293b8fSAndroid Build Coastguard Worker TEST_F(LocalUpdatableMapsTest, same_map_new_name) {
139*eb293b8fSAndroid Build Coastguard Worker TemporaryFile tf;
140*eb293b8fSAndroid Build Coastguard Worker ASSERT_TRUE(
141*eb293b8fSAndroid Build Coastguard Worker android::base::WriteStringToFile("3000-4000 r-xp 00000 00:00 0 /fake/lib.so\n"
142*eb293b8fSAndroid Build Coastguard Worker "8000-9000 r-xp 00000 00:00 0\n",
143*eb293b8fSAndroid Build Coastguard Worker tf.path));
144*eb293b8fSAndroid Build Coastguard Worker
145*eb293b8fSAndroid Build Coastguard Worker maps_.TestSetMapsFile(tf.path);
146*eb293b8fSAndroid Build Coastguard Worker ASSERT_TRUE(maps_.Reparse());
147*eb293b8fSAndroid Build Coastguard Worker ASSERT_EQ(2U, maps_.Total());
148*eb293b8fSAndroid Build Coastguard Worker
149*eb293b8fSAndroid Build Coastguard Worker auto map_info = maps_.Get(0);
150*eb293b8fSAndroid Build Coastguard Worker ASSERT_TRUE(map_info != nullptr);
151*eb293b8fSAndroid Build Coastguard Worker EXPECT_EQ(0x3000U, map_info->start());
152*eb293b8fSAndroid Build Coastguard Worker EXPECT_EQ(0x4000U, map_info->end());
153*eb293b8fSAndroid Build Coastguard Worker EXPECT_EQ(0U, map_info->offset());
154*eb293b8fSAndroid Build Coastguard Worker EXPECT_EQ(PROT_READ | PROT_EXEC, map_info->flags());
155*eb293b8fSAndroid Build Coastguard Worker EXPECT_EQ("/fake/lib.so", map_info->name());
156*eb293b8fSAndroid Build Coastguard Worker EXPECT_EQ(nullptr, map_info->prev_map());
157*eb293b8fSAndroid Build Coastguard Worker EXPECT_EQ(maps_.Get(1), map_info->next_map());
158*eb293b8fSAndroid Build Coastguard Worker
159*eb293b8fSAndroid Build Coastguard Worker map_info = maps_.Get(1);
160*eb293b8fSAndroid Build Coastguard Worker ASSERT_TRUE(map_info != nullptr);
161*eb293b8fSAndroid Build Coastguard Worker EXPECT_EQ(0x8000U, map_info->start());
162*eb293b8fSAndroid Build Coastguard Worker EXPECT_EQ(0x9000U, map_info->end());
163*eb293b8fSAndroid Build Coastguard Worker EXPECT_EQ(0U, map_info->offset());
164*eb293b8fSAndroid Build Coastguard Worker EXPECT_EQ(PROT_READ | PROT_EXEC, map_info->flags());
165*eb293b8fSAndroid Build Coastguard Worker EXPECT_TRUE(map_info->name().empty());
166*eb293b8fSAndroid Build Coastguard Worker EXPECT_EQ(maps_.Get(0), map_info->prev_map());
167*eb293b8fSAndroid Build Coastguard Worker EXPECT_EQ(nullptr, map_info->next_map());
168*eb293b8fSAndroid Build Coastguard Worker }
169*eb293b8fSAndroid Build Coastguard Worker
TEST_F(LocalUpdatableMapsTest,only_add_maps)170*eb293b8fSAndroid Build Coastguard Worker TEST_F(LocalUpdatableMapsTest, only_add_maps) {
171*eb293b8fSAndroid Build Coastguard Worker TemporaryFile tf;
172*eb293b8fSAndroid Build Coastguard Worker ASSERT_TRUE(
173*eb293b8fSAndroid Build Coastguard Worker android::base::WriteStringToFile("1000-2000 r-xp 00000 00:00 0\n"
174*eb293b8fSAndroid Build Coastguard Worker "3000-4000 r-xp 00000 00:00 0\n"
175*eb293b8fSAndroid Build Coastguard Worker "8000-9000 r-xp 00000 00:00 0\n"
176*eb293b8fSAndroid Build Coastguard Worker "a000-f000 r-xp 00000 00:00 0\n",
177*eb293b8fSAndroid Build Coastguard Worker tf.path));
178*eb293b8fSAndroid Build Coastguard Worker
179*eb293b8fSAndroid Build Coastguard Worker maps_.TestSetMapsFile(tf.path);
180*eb293b8fSAndroid Build Coastguard Worker ASSERT_TRUE(maps_.Reparse());
181*eb293b8fSAndroid Build Coastguard Worker ASSERT_EQ(4U, maps_.Total());
182*eb293b8fSAndroid Build Coastguard Worker
183*eb293b8fSAndroid Build Coastguard Worker auto map_info = maps_.Get(0);
184*eb293b8fSAndroid Build Coastguard Worker ASSERT_TRUE(map_info != nullptr);
185*eb293b8fSAndroid Build Coastguard Worker EXPECT_EQ(0x1000U, map_info->start());
186*eb293b8fSAndroid Build Coastguard Worker EXPECT_EQ(0x2000U, map_info->end());
187*eb293b8fSAndroid Build Coastguard Worker EXPECT_EQ(0U, map_info->offset());
188*eb293b8fSAndroid Build Coastguard Worker EXPECT_EQ(PROT_READ | PROT_EXEC, map_info->flags());
189*eb293b8fSAndroid Build Coastguard Worker EXPECT_TRUE(map_info->name().empty());
190*eb293b8fSAndroid Build Coastguard Worker EXPECT_EQ(nullptr, map_info->prev_map());
191*eb293b8fSAndroid Build Coastguard Worker EXPECT_EQ(maps_.Get(1), map_info->next_map());
192*eb293b8fSAndroid Build Coastguard Worker
193*eb293b8fSAndroid Build Coastguard Worker map_info = maps_.Get(1);
194*eb293b8fSAndroid Build Coastguard Worker ASSERT_TRUE(map_info != nullptr);
195*eb293b8fSAndroid Build Coastguard Worker EXPECT_EQ(0x3000U, map_info->start());
196*eb293b8fSAndroid Build Coastguard Worker EXPECT_EQ(0x4000U, map_info->end());
197*eb293b8fSAndroid Build Coastguard Worker EXPECT_EQ(0U, map_info->offset());
198*eb293b8fSAndroid Build Coastguard Worker EXPECT_EQ(PROT_READ | PROT_EXEC, map_info->flags());
199*eb293b8fSAndroid Build Coastguard Worker EXPECT_TRUE(map_info->name().empty());
200*eb293b8fSAndroid Build Coastguard Worker EXPECT_EQ(maps_.Get(0), map_info->prev_map());
201*eb293b8fSAndroid Build Coastguard Worker EXPECT_EQ(maps_.Get(2), map_info->next_map());
202*eb293b8fSAndroid Build Coastguard Worker
203*eb293b8fSAndroid Build Coastguard Worker map_info = maps_.Get(2);
204*eb293b8fSAndroid Build Coastguard Worker ASSERT_TRUE(map_info != nullptr);
205*eb293b8fSAndroid Build Coastguard Worker EXPECT_EQ(0x8000U, map_info->start());
206*eb293b8fSAndroid Build Coastguard Worker EXPECT_EQ(0x9000U, map_info->end());
207*eb293b8fSAndroid Build Coastguard Worker EXPECT_EQ(0U, map_info->offset());
208*eb293b8fSAndroid Build Coastguard Worker EXPECT_EQ(PROT_READ | PROT_EXEC, map_info->flags());
209*eb293b8fSAndroid Build Coastguard Worker EXPECT_TRUE(map_info->name().empty());
210*eb293b8fSAndroid Build Coastguard Worker EXPECT_EQ(maps_.Get(1), map_info->prev_map());
211*eb293b8fSAndroid Build Coastguard Worker EXPECT_EQ(maps_.Get(3), map_info->next_map());
212*eb293b8fSAndroid Build Coastguard Worker
213*eb293b8fSAndroid Build Coastguard Worker map_info = maps_.Get(3);
214*eb293b8fSAndroid Build Coastguard Worker ASSERT_TRUE(map_info != nullptr);
215*eb293b8fSAndroid Build Coastguard Worker EXPECT_EQ(0xa000U, map_info->start());
216*eb293b8fSAndroid Build Coastguard Worker EXPECT_EQ(0xf000U, map_info->end());
217*eb293b8fSAndroid Build Coastguard Worker EXPECT_EQ(0U, map_info->offset());
218*eb293b8fSAndroid Build Coastguard Worker EXPECT_EQ(PROT_READ | PROT_EXEC, map_info->flags());
219*eb293b8fSAndroid Build Coastguard Worker EXPECT_TRUE(map_info->name().empty());
220*eb293b8fSAndroid Build Coastguard Worker EXPECT_EQ(maps_.Get(2), map_info->prev_map());
221*eb293b8fSAndroid Build Coastguard Worker EXPECT_EQ(nullptr, map_info->next_map());
222*eb293b8fSAndroid Build Coastguard Worker }
223*eb293b8fSAndroid Build Coastguard Worker
TEST_F(LocalUpdatableMapsTest,all_new_maps)224*eb293b8fSAndroid Build Coastguard Worker TEST_F(LocalUpdatableMapsTest, all_new_maps) {
225*eb293b8fSAndroid Build Coastguard Worker TemporaryFile tf;
226*eb293b8fSAndroid Build Coastguard Worker ASSERT_TRUE(
227*eb293b8fSAndroid Build Coastguard Worker android::base::WriteStringToFile("1000-2000 r-xp 00000 00:00 0\n"
228*eb293b8fSAndroid Build Coastguard Worker "a000-f000 r-xp 00000 00:00 0\n",
229*eb293b8fSAndroid Build Coastguard Worker tf.path));
230*eb293b8fSAndroid Build Coastguard Worker
231*eb293b8fSAndroid Build Coastguard Worker maps_.TestSetMapsFile(tf.path);
232*eb293b8fSAndroid Build Coastguard Worker ASSERT_TRUE(maps_.Reparse());
233*eb293b8fSAndroid Build Coastguard Worker ASSERT_EQ(2U, maps_.Total());
234*eb293b8fSAndroid Build Coastguard Worker
235*eb293b8fSAndroid Build Coastguard Worker auto map_info = maps_.Get(0);
236*eb293b8fSAndroid Build Coastguard Worker ASSERT_TRUE(map_info != nullptr);
237*eb293b8fSAndroid Build Coastguard Worker EXPECT_EQ(0x1000U, map_info->start());
238*eb293b8fSAndroid Build Coastguard Worker EXPECT_EQ(0x2000U, map_info->end());
239*eb293b8fSAndroid Build Coastguard Worker EXPECT_EQ(0U, map_info->offset());
240*eb293b8fSAndroid Build Coastguard Worker EXPECT_EQ(PROT_READ | PROT_EXEC, map_info->flags());
241*eb293b8fSAndroid Build Coastguard Worker EXPECT_TRUE(map_info->name().empty());
242*eb293b8fSAndroid Build Coastguard Worker EXPECT_EQ(nullptr, map_info->prev_map());
243*eb293b8fSAndroid Build Coastguard Worker EXPECT_EQ(maps_.Get(1), map_info->next_map());
244*eb293b8fSAndroid Build Coastguard Worker
245*eb293b8fSAndroid Build Coastguard Worker map_info = maps_.Get(1);
246*eb293b8fSAndroid Build Coastguard Worker ASSERT_TRUE(map_info != nullptr);
247*eb293b8fSAndroid Build Coastguard Worker EXPECT_EQ(0xa000U, map_info->start());
248*eb293b8fSAndroid Build Coastguard Worker EXPECT_EQ(0xf000U, map_info->end());
249*eb293b8fSAndroid Build Coastguard Worker EXPECT_EQ(0U, map_info->offset());
250*eb293b8fSAndroid Build Coastguard Worker EXPECT_EQ(PROT_READ | PROT_EXEC, map_info->flags());
251*eb293b8fSAndroid Build Coastguard Worker EXPECT_TRUE(map_info->name().empty());
252*eb293b8fSAndroid Build Coastguard Worker EXPECT_EQ(maps_.Get(0), map_info->prev_map());
253*eb293b8fSAndroid Build Coastguard Worker EXPECT_EQ(nullptr, map_info->next_map());
254*eb293b8fSAndroid Build Coastguard Worker }
255*eb293b8fSAndroid Build Coastguard Worker
TEST_F(LocalUpdatableMapsTest,add_map_prev_name_updated)256*eb293b8fSAndroid Build Coastguard Worker TEST_F(LocalUpdatableMapsTest, add_map_prev_name_updated) {
257*eb293b8fSAndroid Build Coastguard Worker TemporaryFile tf;
258*eb293b8fSAndroid Build Coastguard Worker ASSERT_TRUE(
259*eb293b8fSAndroid Build Coastguard Worker android::base::WriteStringToFile("3000-4000 rwxp 00000 00:00 0\n"
260*eb293b8fSAndroid Build Coastguard Worker "8000-9000 r-xp 00000 00:00 0\n"
261*eb293b8fSAndroid Build Coastguard Worker "9000-a000 r-xp 00000 00:00 0\n",
262*eb293b8fSAndroid Build Coastguard Worker tf.path));
263*eb293b8fSAndroid Build Coastguard Worker
264*eb293b8fSAndroid Build Coastguard Worker maps_.TestSetMapsFile(tf.path);
265*eb293b8fSAndroid Build Coastguard Worker ASSERT_TRUE(maps_.Reparse());
266*eb293b8fSAndroid Build Coastguard Worker ASSERT_EQ(3U, maps_.Total());
267*eb293b8fSAndroid Build Coastguard Worker
268*eb293b8fSAndroid Build Coastguard Worker auto map_info = maps_.Get(2);
269*eb293b8fSAndroid Build Coastguard Worker ASSERT_TRUE(map_info != nullptr);
270*eb293b8fSAndroid Build Coastguard Worker EXPECT_EQ(0x9000U, map_info->start());
271*eb293b8fSAndroid Build Coastguard Worker EXPECT_EQ(0xA000U, map_info->end());
272*eb293b8fSAndroid Build Coastguard Worker EXPECT_EQ(0U, map_info->offset());
273*eb293b8fSAndroid Build Coastguard Worker EXPECT_EQ(PROT_READ | PROT_EXEC, map_info->flags());
274*eb293b8fSAndroid Build Coastguard Worker EXPECT_TRUE(map_info->name().empty());
275*eb293b8fSAndroid Build Coastguard Worker
276*eb293b8fSAndroid Build Coastguard Worker // Check all of the prev and next pointers.
277*eb293b8fSAndroid Build Coastguard Worker EXPECT_EQ(nullptr, maps_.Get(0)->prev_map());
278*eb293b8fSAndroid Build Coastguard Worker EXPECT_EQ(maps_.Get(1), maps_.Get(0)->next_map());
279*eb293b8fSAndroid Build Coastguard Worker EXPECT_EQ(maps_.Get(0), maps_.Get(1)->prev_map());
280*eb293b8fSAndroid Build Coastguard Worker EXPECT_EQ(maps_.Get(2), maps_.Get(1)->next_map());
281*eb293b8fSAndroid Build Coastguard Worker EXPECT_EQ(maps_.Get(1), maps_.Get(2)->prev_map());
282*eb293b8fSAndroid Build Coastguard Worker EXPECT_EQ(nullptr, maps_.Get(2)->next_map());
283*eb293b8fSAndroid Build Coastguard Worker }
284*eb293b8fSAndroid Build Coastguard Worker
TEST_F(LocalUpdatableMapsTest,add_map_prev_real_name_updated)285*eb293b8fSAndroid Build Coastguard Worker TEST_F(LocalUpdatableMapsTest, add_map_prev_real_name_updated) {
286*eb293b8fSAndroid Build Coastguard Worker TemporaryFile tf;
287*eb293b8fSAndroid Build Coastguard Worker ASSERT_TRUE(
288*eb293b8fSAndroid Build Coastguard Worker android::base::WriteStringToFile("3000-4000 r-xp 00000 00:00 0 /fake/lib.so\n"
289*eb293b8fSAndroid Build Coastguard Worker "4000-5000 ---p 00000 00:00 0\n"
290*eb293b8fSAndroid Build Coastguard Worker "7000-8000 r-xp 00000 00:00 0 /fake/lib.so\n"
291*eb293b8fSAndroid Build Coastguard Worker "8000-9000 ---p 00000 00:00 0\n",
292*eb293b8fSAndroid Build Coastguard Worker tf.path));
293*eb293b8fSAndroid Build Coastguard Worker
294*eb293b8fSAndroid Build Coastguard Worker maps_.TestSetMapsFile(tf.path);
295*eb293b8fSAndroid Build Coastguard Worker bool any_changed;
296*eb293b8fSAndroid Build Coastguard Worker ASSERT_TRUE(maps_.Reparse(&any_changed));
297*eb293b8fSAndroid Build Coastguard Worker ASSERT_EQ(4U, maps_.Total());
298*eb293b8fSAndroid Build Coastguard Worker ASSERT_TRUE(any_changed);
299*eb293b8fSAndroid Build Coastguard Worker
300*eb293b8fSAndroid Build Coastguard Worker // Try again and assert there are no changes this time.
301*eb293b8fSAndroid Build Coastguard Worker ASSERT_TRUE(maps_.Reparse(&any_changed));
302*eb293b8fSAndroid Build Coastguard Worker ASSERT_EQ(4U, maps_.Total());
303*eb293b8fSAndroid Build Coastguard Worker ASSERT_FALSE(any_changed);
304*eb293b8fSAndroid Build Coastguard Worker
305*eb293b8fSAndroid Build Coastguard Worker auto map_info = maps_.Get(2);
306*eb293b8fSAndroid Build Coastguard Worker ASSERT_TRUE(map_info != nullptr);
307*eb293b8fSAndroid Build Coastguard Worker EXPECT_EQ(0x7000U, map_info->start());
308*eb293b8fSAndroid Build Coastguard Worker EXPECT_EQ(0x8000U, map_info->end());
309*eb293b8fSAndroid Build Coastguard Worker EXPECT_EQ(0U, map_info->offset());
310*eb293b8fSAndroid Build Coastguard Worker EXPECT_EQ(PROT_READ | PROT_EXEC, map_info->flags());
311*eb293b8fSAndroid Build Coastguard Worker EXPECT_EQ(maps_.Get(0), map_info->GetPrevRealMap());
312*eb293b8fSAndroid Build Coastguard Worker EXPECT_EQ(maps_.Get(1), map_info->prev_map());
313*eb293b8fSAndroid Build Coastguard Worker EXPECT_EQ(maps_.Get(3), map_info->next_map());
314*eb293b8fSAndroid Build Coastguard Worker EXPECT_EQ("/fake/lib.so", map_info->name());
315*eb293b8fSAndroid Build Coastguard Worker
316*eb293b8fSAndroid Build Coastguard Worker map_info = maps_.Get(3);
317*eb293b8fSAndroid Build Coastguard Worker ASSERT_TRUE(map_info != nullptr);
318*eb293b8fSAndroid Build Coastguard Worker EXPECT_EQ(0x8000U, map_info->start());
319*eb293b8fSAndroid Build Coastguard Worker EXPECT_EQ(0x9000U, map_info->end());
320*eb293b8fSAndroid Build Coastguard Worker EXPECT_EQ(0U, map_info->offset());
321*eb293b8fSAndroid Build Coastguard Worker EXPECT_TRUE(map_info->IsBlank());
322*eb293b8fSAndroid Build Coastguard Worker EXPECT_EQ(nullptr, map_info->GetPrevRealMap());
323*eb293b8fSAndroid Build Coastguard Worker EXPECT_EQ(maps_.Get(2), map_info->prev_map());
324*eb293b8fSAndroid Build Coastguard Worker EXPECT_EQ(maps_.Get(4), map_info->next_map());
325*eb293b8fSAndroid Build Coastguard Worker EXPECT_TRUE(map_info->name().empty());
326*eb293b8fSAndroid Build Coastguard Worker
327*eb293b8fSAndroid Build Coastguard Worker ASSERT_TRUE(
328*eb293b8fSAndroid Build Coastguard Worker android::base::WriteStringToFile("3000-4000 r-xp 00000 00:00 0 /fake/lib.so\n"
329*eb293b8fSAndroid Build Coastguard Worker "4000-5000 ---p 00000 00:00 0\n"
330*eb293b8fSAndroid Build Coastguard Worker "7000-8000 r-xp 00000 00:00 0 /fake/lib.so\n"
331*eb293b8fSAndroid Build Coastguard Worker "8000-9000 ---p 00000 00:00 0\n"
332*eb293b8fSAndroid Build Coastguard Worker "9000-a000 r-xp 00000 00:00 0 /fake/lib2.so\n"
333*eb293b8fSAndroid Build Coastguard Worker "a000-b000 r-xp 00000 00:00 0 /fake/lib3.so\n",
334*eb293b8fSAndroid Build Coastguard Worker tf.path));
335*eb293b8fSAndroid Build Coastguard Worker
336*eb293b8fSAndroid Build Coastguard Worker maps_.TestSetMapsFile(tf.path);
337*eb293b8fSAndroid Build Coastguard Worker ASSERT_TRUE(maps_.Reparse(&any_changed));
338*eb293b8fSAndroid Build Coastguard Worker ASSERT_EQ(6U, maps_.Total());
339*eb293b8fSAndroid Build Coastguard Worker ASSERT_TRUE(any_changed);
340*eb293b8fSAndroid Build Coastguard Worker
341*eb293b8fSAndroid Build Coastguard Worker // Try again and assert there are no changes this time.
342*eb293b8fSAndroid Build Coastguard Worker ASSERT_TRUE(maps_.Reparse(&any_changed));
343*eb293b8fSAndroid Build Coastguard Worker ASSERT_EQ(6U, maps_.Total());
344*eb293b8fSAndroid Build Coastguard Worker ASSERT_FALSE(any_changed);
345*eb293b8fSAndroid Build Coastguard Worker
346*eb293b8fSAndroid Build Coastguard Worker map_info = maps_.Get(2);
347*eb293b8fSAndroid Build Coastguard Worker ASSERT_TRUE(map_info != nullptr);
348*eb293b8fSAndroid Build Coastguard Worker EXPECT_EQ(0x7000U, map_info->start());
349*eb293b8fSAndroid Build Coastguard Worker EXPECT_EQ(0x8000U, map_info->end());
350*eb293b8fSAndroid Build Coastguard Worker EXPECT_EQ(0U, map_info->offset());
351*eb293b8fSAndroid Build Coastguard Worker EXPECT_EQ(PROT_READ | PROT_EXEC, map_info->flags());
352*eb293b8fSAndroid Build Coastguard Worker EXPECT_EQ("/fake/lib.so", map_info->name());
353*eb293b8fSAndroid Build Coastguard Worker EXPECT_EQ(maps_.Get(1), map_info->prev_map());
354*eb293b8fSAndroid Build Coastguard Worker EXPECT_EQ(maps_.Get(0), map_info->GetPrevRealMap());
355*eb293b8fSAndroid Build Coastguard Worker EXPECT_EQ(maps_.Get(3), map_info->next_map());
356*eb293b8fSAndroid Build Coastguard Worker
357*eb293b8fSAndroid Build Coastguard Worker map_info = maps_.Get(4);
358*eb293b8fSAndroid Build Coastguard Worker ASSERT_TRUE(map_info != nullptr);
359*eb293b8fSAndroid Build Coastguard Worker EXPECT_EQ(0x9000U, map_info->start());
360*eb293b8fSAndroid Build Coastguard Worker EXPECT_EQ(0xA000U, map_info->end());
361*eb293b8fSAndroid Build Coastguard Worker EXPECT_EQ(0U, map_info->offset());
362*eb293b8fSAndroid Build Coastguard Worker EXPECT_EQ(PROT_READ | PROT_EXEC, map_info->flags());
363*eb293b8fSAndroid Build Coastguard Worker EXPECT_EQ("/fake/lib2.so", map_info->name());
364*eb293b8fSAndroid Build Coastguard Worker EXPECT_EQ(maps_.Get(3), map_info->prev_map());
365*eb293b8fSAndroid Build Coastguard Worker EXPECT_EQ(nullptr, map_info->GetPrevRealMap());
366*eb293b8fSAndroid Build Coastguard Worker EXPECT_EQ(maps_.Get(5), map_info->next_map());
367*eb293b8fSAndroid Build Coastguard Worker
368*eb293b8fSAndroid Build Coastguard Worker map_info = maps_.Get(5);
369*eb293b8fSAndroid Build Coastguard Worker ASSERT_TRUE(map_info != nullptr);
370*eb293b8fSAndroid Build Coastguard Worker EXPECT_EQ(0xA000U, map_info->start());
371*eb293b8fSAndroid Build Coastguard Worker EXPECT_EQ(0xB000U, map_info->end());
372*eb293b8fSAndroid Build Coastguard Worker EXPECT_EQ(0U, map_info->offset());
373*eb293b8fSAndroid Build Coastguard Worker EXPECT_EQ(PROT_READ | PROT_EXEC, map_info->flags());
374*eb293b8fSAndroid Build Coastguard Worker EXPECT_EQ("/fake/lib3.so", map_info->name());
375*eb293b8fSAndroid Build Coastguard Worker EXPECT_EQ(maps_.Get(4), map_info->prev_map());
376*eb293b8fSAndroid Build Coastguard Worker EXPECT_EQ(nullptr, map_info->GetPrevRealMap());
377*eb293b8fSAndroid Build Coastguard Worker EXPECT_EQ(nullptr, map_info->next_map());
378*eb293b8fSAndroid Build Coastguard Worker }
379*eb293b8fSAndroid Build Coastguard Worker
380*eb293b8fSAndroid Build Coastguard Worker } // namespace unwindstack
381