xref: /aosp_15_r20/system/unwinding/libunwindstack/tests/GlobalTest.cpp (revision eb293b8f56ee8303637c5595cfcdeef8039e85c6)
1*eb293b8fSAndroid Build Coastguard Worker /*
2*eb293b8fSAndroid Build Coastguard Worker  * Copyright (C) 2021 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 
19*eb293b8fSAndroid Build Coastguard Worker #include <gmock/gmock.h>
20*eb293b8fSAndroid Build Coastguard Worker #include <gtest/gtest.h>
21*eb293b8fSAndroid Build Coastguard Worker 
22*eb293b8fSAndroid Build Coastguard Worker #include <memory>
23*eb293b8fSAndroid Build Coastguard Worker #include <string>
24*eb293b8fSAndroid Build Coastguard Worker #include <vector>
25*eb293b8fSAndroid Build Coastguard Worker 
26*eb293b8fSAndroid Build Coastguard Worker #include <unwindstack/Elf.h>
27*eb293b8fSAndroid Build Coastguard Worker #include <unwindstack/Global.h>
28*eb293b8fSAndroid Build Coastguard Worker #include <unwindstack/MapInfo.h>
29*eb293b8fSAndroid Build Coastguard Worker #include <unwindstack/Maps.h>
30*eb293b8fSAndroid Build Coastguard Worker 
31*eb293b8fSAndroid Build Coastguard Worker #include "ElfFake.h"
32*eb293b8fSAndroid Build Coastguard Worker 
33*eb293b8fSAndroid Build Coastguard Worker using ::testing::_;
34*eb293b8fSAndroid Build Coastguard Worker using ::testing::DoAll;
35*eb293b8fSAndroid Build Coastguard Worker using ::testing::Return;
36*eb293b8fSAndroid Build Coastguard Worker using ::testing::SetArgPointee;
37*eb293b8fSAndroid Build Coastguard Worker 
38*eb293b8fSAndroid Build Coastguard Worker namespace unwindstack {
39*eb293b8fSAndroid Build Coastguard Worker 
40*eb293b8fSAndroid Build Coastguard Worker class GlobalMock : public Global {
41*eb293b8fSAndroid Build Coastguard Worker  public:
GlobalMock(std::shared_ptr<Memory> & memory)42*eb293b8fSAndroid Build Coastguard Worker   explicit GlobalMock(std::shared_ptr<Memory>& memory) : Global(memory) {}
GlobalMock(std::shared_ptr<Memory> & memory,std::vector<std::string> & search_libs)43*eb293b8fSAndroid Build Coastguard Worker   GlobalMock(std::shared_ptr<Memory>& memory, std::vector<std::string>& search_libs)
44*eb293b8fSAndroid Build Coastguard Worker       : Global(memory, search_libs) {}
45*eb293b8fSAndroid Build Coastguard Worker 
46*eb293b8fSAndroid Build Coastguard Worker   MOCK_METHOD(bool, ReadVariableData, (uint64_t), (override));
47*eb293b8fSAndroid Build Coastguard Worker 
48*eb293b8fSAndroid Build Coastguard Worker   MOCK_METHOD(void, ProcessArch, (), (override));
49*eb293b8fSAndroid Build Coastguard Worker 
TestFindAndReadVariable(Maps * maps,const char * var_str)50*eb293b8fSAndroid Build Coastguard Worker   void TestFindAndReadVariable(Maps* maps, const char* var_str) {
51*eb293b8fSAndroid Build Coastguard Worker     FindAndReadVariable(maps, var_str);
52*eb293b8fSAndroid Build Coastguard Worker   }
53*eb293b8fSAndroid Build Coastguard Worker };
54*eb293b8fSAndroid Build Coastguard Worker 
55*eb293b8fSAndroid Build Coastguard Worker class GlobalTest : public ::testing::Test {
56*eb293b8fSAndroid Build Coastguard Worker  protected:
SetUp()57*eb293b8fSAndroid Build Coastguard Worker   void SetUp() override {
58*eb293b8fSAndroid Build Coastguard Worker     maps_.reset(
59*eb293b8fSAndroid Build Coastguard Worker         new BufferMaps("10000-11000 r--p 0000 00:00 0 first.so\n"
60*eb293b8fSAndroid Build Coastguard Worker                        "11000-12000 r-xp 1000 00:00 0 first.so\n"
61*eb293b8fSAndroid Build Coastguard Worker                        "12000-13000 rw-p 2000 00:00 0 first.so\n"
62*eb293b8fSAndroid Build Coastguard Worker 
63*eb293b8fSAndroid Build Coastguard Worker                        "20000-22000 r--p 0000 00:00 0 second.so\n"
64*eb293b8fSAndroid Build Coastguard Worker                        "22000-23000 rw-p 2000 00:00 0 second.so\n"
65*eb293b8fSAndroid Build Coastguard Worker 
66*eb293b8fSAndroid Build Coastguard Worker                        "30000-31000 r--p 0000 00:00 0 third.so\n"
67*eb293b8fSAndroid Build Coastguard Worker                        "31000-32000 ---p 0000 00:00 0\n"
68*eb293b8fSAndroid Build Coastguard Worker                        "32000-33000 r-xp 1000 00:00 0 third.so\n"
69*eb293b8fSAndroid Build Coastguard Worker                        "33000-34000 rw-p 2000 00:00 0 third.so\n"
70*eb293b8fSAndroid Build Coastguard Worker 
71*eb293b8fSAndroid Build Coastguard Worker                        "40000-42000 r--p 0000 00:00 0 fourth.so\n"
72*eb293b8fSAndroid Build Coastguard Worker                        "42000-43000 rw-p 0000 00:00 0 fourth.so\n"));
73*eb293b8fSAndroid Build Coastguard Worker     ASSERT_TRUE(maps_->Parse());
74*eb293b8fSAndroid Build Coastguard Worker     ASSERT_EQ(11U, maps_->Total());
75*eb293b8fSAndroid Build Coastguard Worker 
76*eb293b8fSAndroid Build Coastguard Worker     std::shared_ptr<Memory> empty;
77*eb293b8fSAndroid Build Coastguard Worker     elf_fakes_.push_back(new ElfInterfaceFake(empty));
78*eb293b8fSAndroid Build Coastguard Worker     elf_fakes_.push_back(new ElfInterfaceFake(empty));
79*eb293b8fSAndroid Build Coastguard Worker     elf_fakes_.push_back(new ElfInterfaceFake(empty));
80*eb293b8fSAndroid Build Coastguard Worker     elf_fakes_.push_back(new ElfInterfaceFake(empty));
81*eb293b8fSAndroid Build Coastguard Worker 
82*eb293b8fSAndroid Build Coastguard Worker     ElfFake* elf_fake = new ElfFake(empty);
83*eb293b8fSAndroid Build Coastguard Worker     elf_fake->FakeSetValid(true);
84*eb293b8fSAndroid Build Coastguard Worker     elf_fake->FakeSetInterface(elf_fakes_[0]);
85*eb293b8fSAndroid Build Coastguard Worker     elf_fakes_[0]->FakeSetDataVaddrStart(0x2000);
86*eb293b8fSAndroid Build Coastguard Worker     elf_fakes_[0]->FakeSetDataVaddrEnd(0x3000);
87*eb293b8fSAndroid Build Coastguard Worker     elf_fakes_[0]->FakeSetDataOffset(0x2000);
88*eb293b8fSAndroid Build Coastguard Worker     auto map_info = maps_->Find(0x10000);
89*eb293b8fSAndroid Build Coastguard Worker     map_info->GetElfFields().elf_.reset(elf_fake);
90*eb293b8fSAndroid Build Coastguard Worker 
91*eb293b8fSAndroid Build Coastguard Worker     elf_fake = new ElfFake(empty);
92*eb293b8fSAndroid Build Coastguard Worker     elf_fake->FakeSetValid(true);
93*eb293b8fSAndroid Build Coastguard Worker     elf_fake->FakeSetInterface(elf_fakes_[1]);
94*eb293b8fSAndroid Build Coastguard Worker     elf_fakes_[1]->FakeSetDataVaddrStart(0x2000);
95*eb293b8fSAndroid Build Coastguard Worker     elf_fakes_[1]->FakeSetDataVaddrEnd(0x3000);
96*eb293b8fSAndroid Build Coastguard Worker     elf_fakes_[1]->FakeSetDataOffset(0x2000);
97*eb293b8fSAndroid Build Coastguard Worker     map_info = maps_->Find(0x20000);
98*eb293b8fSAndroid Build Coastguard Worker     map_info->GetElfFields().elf_.reset(elf_fake);
99*eb293b8fSAndroid Build Coastguard Worker 
100*eb293b8fSAndroid Build Coastguard Worker     elf_fake = new ElfFake(empty);
101*eb293b8fSAndroid Build Coastguard Worker     elf_fake->FakeSetValid(true);
102*eb293b8fSAndroid Build Coastguard Worker     elf_fake->FakeSetInterface(elf_fakes_[2]);
103*eb293b8fSAndroid Build Coastguard Worker     elf_fakes_[2]->FakeSetDataVaddrStart(0x2000);
104*eb293b8fSAndroid Build Coastguard Worker     elf_fakes_[2]->FakeSetDataVaddrEnd(0x3000);
105*eb293b8fSAndroid Build Coastguard Worker     elf_fakes_[2]->FakeSetDataOffset(0x2000);
106*eb293b8fSAndroid Build Coastguard Worker     map_info = maps_->Find(0x30000);
107*eb293b8fSAndroid Build Coastguard Worker     map_info->GetElfFields().elf_.reset(elf_fake);
108*eb293b8fSAndroid Build Coastguard Worker 
109*eb293b8fSAndroid Build Coastguard Worker     elf_fake = new ElfFake(empty);
110*eb293b8fSAndroid Build Coastguard Worker     elf_fake->FakeSetValid(true);
111*eb293b8fSAndroid Build Coastguard Worker     elf_fake->FakeSetInterface(elf_fakes_[3]);
112*eb293b8fSAndroid Build Coastguard Worker     elf_fakes_[3]->FakeSetDataVaddrStart(00);
113*eb293b8fSAndroid Build Coastguard Worker     elf_fakes_[3]->FakeSetDataVaddrEnd(0x1000);
114*eb293b8fSAndroid Build Coastguard Worker     elf_fakes_[3]->FakeSetDataOffset(0);
115*eb293b8fSAndroid Build Coastguard Worker     map_info = maps_->Find(0x40000);
116*eb293b8fSAndroid Build Coastguard Worker     map_info->GetElfFields().elf_.reset(elf_fake);
117*eb293b8fSAndroid Build Coastguard Worker 
118*eb293b8fSAndroid Build Coastguard Worker     global_.reset(new GlobalMock(empty_));
119*eb293b8fSAndroid Build Coastguard Worker   }
120*eb293b8fSAndroid Build Coastguard Worker 
121*eb293b8fSAndroid Build Coastguard Worker   std::shared_ptr<Memory> empty_;
122*eb293b8fSAndroid Build Coastguard Worker   std::unique_ptr<BufferMaps> maps_;
123*eb293b8fSAndroid Build Coastguard Worker   std::unique_ptr<GlobalMock> global_;
124*eb293b8fSAndroid Build Coastguard Worker   std::vector<ElfInterfaceFake*> elf_fakes_;
125*eb293b8fSAndroid Build Coastguard Worker };
126*eb293b8fSAndroid Build Coastguard Worker 
TEST_F(GlobalTest,ro_rx_rw)127*eb293b8fSAndroid Build Coastguard Worker TEST_F(GlobalTest, ro_rx_rw) {
128*eb293b8fSAndroid Build Coastguard Worker   std::string global_var("fake_global");
129*eb293b8fSAndroid Build Coastguard Worker   elf_fakes_[0]->FakeSetGlobalVariable(global_var, 0x2010);
130*eb293b8fSAndroid Build Coastguard Worker   EXPECT_CALL(*global_, ReadVariableData(0x12010)).WillOnce(Return(true));
131*eb293b8fSAndroid Build Coastguard Worker 
132*eb293b8fSAndroid Build Coastguard Worker   global_->TestFindAndReadVariable(maps_.get(), global_var.c_str());
133*eb293b8fSAndroid Build Coastguard Worker }
134*eb293b8fSAndroid Build Coastguard Worker 
TEST_F(GlobalTest,ro_rx_rw_searchable)135*eb293b8fSAndroid Build Coastguard Worker TEST_F(GlobalTest, ro_rx_rw_searchable) {
136*eb293b8fSAndroid Build Coastguard Worker   std::vector<std::string> search_libs = {"first.so"};
137*eb293b8fSAndroid Build Coastguard Worker   global_.reset(new GlobalMock(empty_, search_libs));
138*eb293b8fSAndroid Build Coastguard Worker 
139*eb293b8fSAndroid Build Coastguard Worker   std::string global_var("fake_global");
140*eb293b8fSAndroid Build Coastguard Worker   elf_fakes_[0]->FakeSetGlobalVariable(global_var, 0x2010);
141*eb293b8fSAndroid Build Coastguard Worker   EXPECT_CALL(*global_, ReadVariableData(0x12010)).WillOnce(Return(true));
142*eb293b8fSAndroid Build Coastguard Worker 
143*eb293b8fSAndroid Build Coastguard Worker   global_->TestFindAndReadVariable(maps_.get(), global_var.c_str());
144*eb293b8fSAndroid Build Coastguard Worker }
145*eb293b8fSAndroid Build Coastguard Worker 
TEST_F(GlobalTest,ro_rx_rw_not_searchable)146*eb293b8fSAndroid Build Coastguard Worker TEST_F(GlobalTest, ro_rx_rw_not_searchable) {
147*eb293b8fSAndroid Build Coastguard Worker   std::vector<std::string> search_libs = {"second.so"};
148*eb293b8fSAndroid Build Coastguard Worker   global_.reset(new GlobalMock(empty_, search_libs));
149*eb293b8fSAndroid Build Coastguard Worker 
150*eb293b8fSAndroid Build Coastguard Worker   std::string global_var("fake_global");
151*eb293b8fSAndroid Build Coastguard Worker   elf_fakes_[0]->FakeSetGlobalVariable(global_var, 0x2010);
152*eb293b8fSAndroid Build Coastguard Worker 
153*eb293b8fSAndroid Build Coastguard Worker   global_->TestFindAndReadVariable(maps_.get(), global_var.c_str());
154*eb293b8fSAndroid Build Coastguard Worker }
155*eb293b8fSAndroid Build Coastguard Worker 
TEST_F(GlobalTest,ro_rw)156*eb293b8fSAndroid Build Coastguard Worker TEST_F(GlobalTest, ro_rw) {
157*eb293b8fSAndroid Build Coastguard Worker   std::string global_var("fake_global");
158*eb293b8fSAndroid Build Coastguard Worker   elf_fakes_[1]->FakeSetGlobalVariable(global_var, 0x2010);
159*eb293b8fSAndroid Build Coastguard Worker   EXPECT_CALL(*global_, ReadVariableData(0x22010)).WillOnce(Return(true));
160*eb293b8fSAndroid Build Coastguard Worker 
161*eb293b8fSAndroid Build Coastguard Worker   global_->TestFindAndReadVariable(maps_.get(), global_var.c_str());
162*eb293b8fSAndroid Build Coastguard Worker }
163*eb293b8fSAndroid Build Coastguard Worker 
TEST_F(GlobalTest,ro_blank_rx_rw)164*eb293b8fSAndroid Build Coastguard Worker TEST_F(GlobalTest, ro_blank_rx_rw) {
165*eb293b8fSAndroid Build Coastguard Worker   std::string global_var("fake_global");
166*eb293b8fSAndroid Build Coastguard Worker   elf_fakes_[2]->FakeSetGlobalVariable(global_var, 0x2010);
167*eb293b8fSAndroid Build Coastguard Worker   EXPECT_CALL(*global_, ReadVariableData(0x33010)).WillOnce(Return(true));
168*eb293b8fSAndroid Build Coastguard Worker 
169*eb293b8fSAndroid Build Coastguard Worker   global_->TestFindAndReadVariable(maps_.get(), global_var.c_str());
170*eb293b8fSAndroid Build Coastguard Worker }
171*eb293b8fSAndroid Build Coastguard Worker 
TEST_F(GlobalTest,ro_rw_with_zero_offset)172*eb293b8fSAndroid Build Coastguard Worker TEST_F(GlobalTest, ro_rw_with_zero_offset) {
173*eb293b8fSAndroid Build Coastguard Worker   std::string global_var("fake_global");
174*eb293b8fSAndroid Build Coastguard Worker   elf_fakes_[3]->FakeSetGlobalVariable(global_var, 0x10);
175*eb293b8fSAndroid Build Coastguard Worker   EXPECT_CALL(*global_, ReadVariableData(0x42010)).WillOnce(Return(true));
176*eb293b8fSAndroid Build Coastguard Worker 
177*eb293b8fSAndroid Build Coastguard Worker   global_->TestFindAndReadVariable(maps_.get(), global_var.c_str());
178*eb293b8fSAndroid Build Coastguard Worker }
179*eb293b8fSAndroid Build Coastguard Worker 
180*eb293b8fSAndroid Build Coastguard Worker }  // namespace unwindstack
181