1/*
2 * Copyright (c) 2021-2023 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 *     http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16#include "dfx_elf.h"
17#include "dfx_maps.h"
18#include <gtest/gtest.h>
19#include <memory>
20#include <sys/types.h>
21
22using namespace OHOS::HiviewDFX;
23using namespace std;
24using namespace testing::ext;
25
26namespace OHOS {
27namespace HiviewDFX {
28namespace {
29const string INVALID_MAP_NAME = "/system/lib64/init/libinit_context111.z.so";
30#ifdef __arm__
31const string MAPS_FILE = "/data/test/resource/testdata/testmaps_32";
32const string VALID_MAP_NAME = "/system/lib/init/libinit_context.z.so";
33const string VALID_MAP_ITEM = "f6d83000-f6d84000 r--p 00001000 b3:07 1892 /system/lib/init/libinit_context.z.so";
34const string INVALID_MAP_ITEM = "f6d83000-f6d84000 r--p 00001000 b3:07 1892 /system/lib/init/libinit_context111.z.so";
35const string VDSO_MAP_ITEM = "f7c21000-f7c22000 r-xp 00000000 00:00 0                                  [vdso]";
36const string ARK_HAP_MAP_NAME = "/system/app/SceneBoard/SceneBoard.hap";
37const string ARK_CODE_MAP_NAME = "[anon:ArkTS Code:libdialog.z.so/Dialog.js]";
38#else
39const string MAPS_FILE = "/data/test/resource/testdata/testmaps_64";
40const string VALID_MAP_NAME = "/system/lib64/init/libinit_context.z.so";
41const string VALID_MAP_ITEM = "7f0ab40000-7f0ab41000 r--p 00000000 b3:07 1882 /system/lib64/init/libinit_context.z.so";
42const string INVALID_MAP_ITEM = "7f0ab40000-7f0ab41000 r--p 00000000 b3:07 1882 \
43    /system/lib64/init/libinit_context111.z.so";
44const string VDSO_MAP_ITEM = "7f8b9df000-7f8b9e0000 r-xp 00000000 00:00 0                              [vdso]";
45const string ARK_HAP_MAP_NAME = "/system/app/SceneBoard/SceneBoard.hap";
46const string ARK_CODE_MAP_NAME = "[anon:ArkTS Code:libdialog.z.so/Dialog.js]";
47#endif
48}
49
50class MapsTest : public testing::Test {
51public:
52    static void SetUpTestCase(void) {}
53    static void TearDownTestCase(void) {}
54    void SetUp() { maps_ = DfxMaps::Create(getpid(), MAPS_FILE); }
55    void TearDown() {}
56
57public:
58    std::shared_ptr<DfxMaps> maps_;
59};
60
61namespace {
62
63/**
64 * @tc.name: FindMapByAddrTest001
65 * @tc.desc: test FindMapByAddr functions
66 * @tc.type: FUNC
67 */
68HWTEST_F(MapsTest, FindMapByAddrTest001, TestSize.Level2)
69{
70    GTEST_LOG_(INFO) << "FindMapByAddrTest001: start.";
71    maps_->Sort(true);
72#ifdef __arm__
73    uintptr_t validAddr = 0xf6d80000;
74#else
75    uintptr_t validAddr = 0x7f8b8f3001;
76#endif
77    const uintptr_t invalidAddr = 0xffffffff;
78    std::shared_ptr<DfxMap> map = nullptr;
79    EXPECT_EQ(true, maps_->FindMapByAddr(validAddr, map));
80    EXPECT_EQ(false, maps_->FindMapByAddr(invalidAddr, map));
81    GTEST_LOG_(INFO) << "FindMapByAddrTest001: end.";
82}
83
84/**
85 * @tc.name: FindMapByFileInfoTest001
86 * @tc.desc: test FindMapByFileInfo functions
87 * @tc.type: FUNC
88 */
89HWTEST_F(MapsTest, FindMapByFileInfoTest001, TestSize.Level2)
90{
91    GTEST_LOG_(INFO) << "FindMapByFileInfoTest001: start.";
92    std::shared_ptr<DfxMap> map = nullptr;
93    EXPECT_EQ(true, maps_->FindMapByFileInfo(VALID_MAP_NAME, 0, map));
94    EXPECT_EQ(false, maps_->FindMapByFileInfo(INVALID_MAP_NAME, 0, map));
95    const uint64_t invalidOffset = 0xffffffff;
96    EXPECT_EQ(false, maps_->FindMapByFileInfo(VALID_MAP_NAME, invalidOffset, map));
97    EXPECT_EQ(false, maps_->FindMapByFileInfo(INVALID_MAP_NAME, invalidOffset, map));
98    GTEST_LOG_(INFO) << "FindMapByFileInfoTest001: end.";
99}
100
101/**
102 * @tc.name: FindMapsByNameTest001
103 * @tc.desc: test FindMapsByName functions
104 * @tc.type: FUNC
105 */
106HWTEST_F(MapsTest, FindMapsByNameTest001, TestSize.Level2)
107{
108    GTEST_LOG_(INFO) << "FindMapsByNameTest001: start.";
109    std::vector<std::shared_ptr<DfxMap>> mapsV;
110    EXPECT_EQ(true, maps_->FindMapsByName(VALID_MAP_NAME, mapsV));
111    mapsV.clear();
112    EXPECT_EQ(false, maps_->FindMapsByName(INVALID_MAP_NAME, mapsV));
113    GTEST_LOG_(INFO) << "FindMapsByNameTest001: end.";
114}
115
116/**
117 * @tc.name: IsArkNameTest001
118 * @tc.desc: test IsArkExecutable functions
119 * @tc.type: FUNC
120 */
121HWTEST_F(MapsTest, IsArkNameTest001, TestSize.Level2)
122{
123    GTEST_LOG_(INFO) << "IsArkNameTest001: start.";
124    std::shared_ptr<DfxMap> map = nullptr;
125    map = std::make_shared<DfxMap>(0, 0, 0, "1", "anon:ArkTS Code");
126    EXPECT_EQ(false, map->IsArkExecutable());
127    map = std::make_shared<DfxMap>(0, 0, 0, "1", "/dev/zero");
128    EXPECT_EQ(false, map->IsArkExecutable());
129    map = std::make_shared<DfxMap>(0, 0, 0, 4, "[anon:ArkTS Code]");
130    EXPECT_EQ(true, map->IsArkExecutable());
131    GTEST_LOG_(INFO) << "IsArkNameTest001: end.";
132}
133
134/**
135 * @tc.name: GetRelPcTest
136 * @tc.desc: test getRelPc no elf
137 * @tc.type: FUNC
138 */
139HWTEST_F(MapsTest, GetRelPcTest, TestSize.Level2)
140{
141    GTEST_LOG_(INFO) << "GetRelPcTest: start.";
142#ifdef __arm__
143    uint64_t pc = 0xf6d83001;
144    const uint64_t invalidOffset = 0x1001;
145#else
146    uint64_t pc = 0x7f0ab40016;
147    const uint64_t invalidOffset = 0x16;
148#endif
149    shared_ptr<DfxMap> map = DfxMap::Create(INVALID_MAP_ITEM, sizeof(INVALID_MAP_ITEM));
150    EXPECT_EQ(true, ((map->GetElf() == nullptr) && (map->GetRelPc(pc) == invalidOffset)));
151    GTEST_LOG_(INFO) << "GetRelPcTest: end.";
152}
153
154/**
155 * @tc.name: ToStringTest
156 * @tc.desc: test ToString
157 * @tc.type: FUNC
158 */
159HWTEST_F(MapsTest, ToStringTest, TestSize.Level2)
160{
161    GTEST_LOG_(INFO) << "ToStringTest: start.";
162    shared_ptr<DfxMap> map = DfxMap::Create(VALID_MAP_ITEM, sizeof(VALID_MAP_ITEM));
163    GTEST_LOG_(INFO) << map->ToString();
164    EXPECT_EQ(true, sizeof(map->ToString()) != 0);
165    GTEST_LOG_(INFO) << "ToStringTest: end.";
166}
167
168/**
169 * @tc.name: CreateMapsTest
170 * @tc.desc: test create maps by pid
171 * @tc.type: FUNC
172 */
173HWTEST_F(MapsTest, CreateMapsTest, TestSize.Level2)
174{
175    GTEST_LOG_(INFO) << "CreateMapsTest: start.";
176    std::shared_ptr<DfxMaps> dfxMaps = DfxMaps::Create(getpid());
177    ASSERT_TRUE(dfxMaps != nullptr);
178    auto maps = dfxMaps->GetMaps();
179    for (auto map : maps) {
180        std::cout << map->ToString();
181    }
182    GTEST_LOG_(INFO) << "CreateMapsTest: end.";
183}
184
185/**
186 * @tc.name: GetStackRangeTest
187 * @tc.desc: test GetStackRange
188 * @tc.type: FUNC
189 */
190HWTEST_F(MapsTest, GetStackRangeTest, TestSize.Level2)
191{
192    GTEST_LOG_(INFO) << "GetStackRangeTest: start.";
193    uintptr_t bottom, top;
194    ASSERT_TRUE(maps_->GetStackRange(bottom, top));
195#ifdef __arm__
196    EXPECT_EQ(bottom, 0xff860000);
197    EXPECT_EQ(top, 0xff881000);
198#else
199    EXPECT_EQ(bottom, 0x7fe37db000);
200    EXPECT_EQ(top, 0x7fe37fc000);
201#endif
202    GTEST_LOG_(INFO) << "GetStackRangeTest: end.";
203}
204
205/**
206 * @tc.name: IsArkExecutedMapTest
207 * @tc.desc: test IsArkExecutedMap
208 * @tc.type: FUNC
209 */
210HWTEST_F(MapsTest, IsArkExecutedMapTest, TestSize.Level2)
211{
212    GTEST_LOG_(INFO) << "IsArkExecutedMapTest: start.";
213    uintptr_t addr;
214#ifdef __arm__
215    addr = 0xffff2001;
216#else
217    addr = 0x7fe37fd001;
218#endif
219    ASSERT_TRUE(maps_->IsArkExecutedMap(addr));
220#ifdef __arm__
221    addr = 0xffff1001;
222#else
223    addr = 0x7fe37fc001;
224#endif
225    ASSERT_FALSE(maps_->IsArkExecutedMap(addr));
226    addr = 0x0;
227    ASSERT_FALSE(maps_->IsArkExecutedMap(addr));
228    maps_->Sort(false);
229    GTEST_LOG_(INFO) << "IsArkExecutedMapTest: end.";
230}
231
232/**
233 * @tc.name: IsVdsoMapTest
234 * @tc.desc: test IsVdsoMap
235 * @tc.type: FUNC
236 */
237HWTEST_F(MapsTest, IsVdsoMapTest, TestSize.Level2)
238{
239    GTEST_LOG_(INFO) << "IsVdsoMapTest: start.";
240    shared_ptr<DfxMap> map = DfxMap::Create(VDSO_MAP_ITEM, sizeof(VDSO_MAP_ITEM));
241    ASSERT_TRUE(map->IsVdsoMap());
242    GTEST_LOG_(INFO) << "IsVdsoMapTest: end.";
243}
244
245/**
246 * @tc.name: IsLegalMapItemTest
247 * @tc.desc: test IsLegalMapItem, IsArkHapMapItem, IsArkCodeMapItem
248 * @tc.type: FUNC
249 */
250HWTEST_F(MapsTest, IsLegalMapItemTest, TestSize.Level2)
251{
252    GTEST_LOG_(INFO) << "IsLegalMapItemTest: start.";
253    ASSERT_TRUE(DfxMaps::IsArkHapMapItem(ARK_HAP_MAP_NAME));
254    ASSERT_TRUE(DfxMaps::IsArkCodeMapItem(ARK_CODE_MAP_NAME));
255    ASSERT_TRUE(DfxMaps::IsLegalMapItem(ARK_CODE_MAP_NAME));
256    GTEST_LOG_(INFO) << "IsLegalMapItemTest: end.";
257}
258}
259} // namespace HiviewDFX
260} // namespace OHOS