1800b99b8Sopenharmony_ci/*
2800b99b8Sopenharmony_ci * Copyright (c) 2022 Huawei Device Co., Ltd.
3800b99b8Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
4800b99b8Sopenharmony_ci * you may not use this file except in compliance with the License.
5800b99b8Sopenharmony_ci * You may obtain a copy of the License at
6800b99b8Sopenharmony_ci *
7800b99b8Sopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
8800b99b8Sopenharmony_ci *
9800b99b8Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
10800b99b8Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
11800b99b8Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12800b99b8Sopenharmony_ci * See the License for the specific language governing permissions and
13800b99b8Sopenharmony_ci * limitations under the License.
14800b99b8Sopenharmony_ci */
15800b99b8Sopenharmony_ci
16800b99b8Sopenharmony_ci#include <gtest/gtest.h>
17800b99b8Sopenharmony_ci#include <ctime>
18800b99b8Sopenharmony_ci#include <securec.h>
19800b99b8Sopenharmony_ci#include <string>
20800b99b8Sopenharmony_ci#include <vector>
21800b99b8Sopenharmony_ci#include <iostream>
22800b99b8Sopenharmony_ci#include "dfx_elf.h"
23800b99b8Sopenharmony_ci#include "elf_imitate.h"
24800b99b8Sopenharmony_ci#include "unwinder_config.h"
25800b99b8Sopenharmony_ci
26800b99b8Sopenharmony_ciusing namespace OHOS::HiviewDFX;
27800b99b8Sopenharmony_ciusing namespace testing::ext;
28800b99b8Sopenharmony_ciusing namespace std;
29800b99b8Sopenharmony_ci
30800b99b8Sopenharmony_ci#define ELF32_FILE "/data/test/resource/testdata/elf32_test"
31800b99b8Sopenharmony_ci#define ELF64_FILE "/data/test/resource/testdata/elf_test"
32800b99b8Sopenharmony_ci#define DUMPCATCHER_ELF_FILE "/system/bin/dumpcatcher"
33800b99b8Sopenharmony_ci#define PT_LOAD_OFFSET 0x001000
34800b99b8Sopenharmony_ci#define PT_LOAD_OFFSET64 0x0000000000002000
35800b99b8Sopenharmony_ci
36800b99b8Sopenharmony_cinamespace OHOS {
37800b99b8Sopenharmony_cinamespace HiviewDFX {
38800b99b8Sopenharmony_ciclass DfxElfTest : public testing::Test {
39800b99b8Sopenharmony_cipublic:
40800b99b8Sopenharmony_ci    static void SetUpTestCase(void) {}
41800b99b8Sopenharmony_ci    static void TearDownTestCase(void) {}
42800b99b8Sopenharmony_ci    void SetUp() {}
43800b99b8Sopenharmony_ci    void TearDown() {}
44800b99b8Sopenharmony_ci};
45800b99b8Sopenharmony_ci
46800b99b8Sopenharmony_cistd::vector<std::string> interestedSections = { ".dynsym", ".eh_frame_hdr", ".eh_frame", ".symtab" };
47800b99b8Sopenharmony_ci /**
48800b99b8Sopenharmony_ci * @tc.name: DfxElfTest001
49800b99b8Sopenharmony_ci * @tc.desc: test DfxElf functions with 32 bit ELF
50800b99b8Sopenharmony_ci * @tc.type: FUNC
51800b99b8Sopenharmony_ci */
52800b99b8Sopenharmony_ciHWTEST_F(DfxElfTest, DfxElfTest001, TestSize.Level2)
53800b99b8Sopenharmony_ci{
54800b99b8Sopenharmony_ci    GTEST_LOG_(INFO) << "DfxElfTest001: start.";
55800b99b8Sopenharmony_ci    DfxElf elf(ELF32_FILE);
56800b99b8Sopenharmony_ci    ASSERT_TRUE(elf.IsValid());
57800b99b8Sopenharmony_ci    ElfImitate elfImitate;
58800b99b8Sopenharmony_ci    ShdrInfo shdr;
59800b99b8Sopenharmony_ci    ShdrInfo shdrImitate;
60800b99b8Sopenharmony_ci    bool ret = elfImitate.ParseAllHeaders(ElfImitate::ElfFileType::ELF32);
61800b99b8Sopenharmony_ci    ASSERT_TRUE(ret);
62800b99b8Sopenharmony_ci    for (size_t i = 0; i < interestedSections.size(); i++) {
63800b99b8Sopenharmony_ci        elf.GetSectionInfo(shdr, interestedSections[i]);
64800b99b8Sopenharmony_ci        elfImitate.GetSectionInfo(shdrImitate, interestedSections[i]);
65800b99b8Sopenharmony_ci        GTEST_LOG_(INFO) << interestedSections[i];
66800b99b8Sopenharmony_ci        ASSERT_EQ(shdr.addr, shdrImitate.addr);
67800b99b8Sopenharmony_ci        ASSERT_EQ(shdr.offset, shdrImitate.offset);
68800b99b8Sopenharmony_ci        ASSERT_EQ(shdr.size, shdrImitate.size);
69800b99b8Sopenharmony_ci    }
70800b99b8Sopenharmony_ci    ASSERT_EQ(elf.GetArchType(), elfImitate.GetArchType());
71800b99b8Sopenharmony_ci    ASSERT_EQ(elf.GetElfSize(), elfImitate.GetElfSize());
72800b99b8Sopenharmony_ci    ASSERT_EQ(elf.GetLoadBias(), elfImitate.GetLoadBias());
73800b99b8Sopenharmony_ci
74800b99b8Sopenharmony_ci    auto load = elf.GetPtLoads();
75800b99b8Sopenharmony_ci    auto loadImitate = elfImitate.GetPtLoads();
76800b99b8Sopenharmony_ci    ASSERT_EQ(load[PT_LOAD_OFFSET].offset, loadImitate[PT_LOAD_OFFSET].offset);
77800b99b8Sopenharmony_ci    ASSERT_EQ(load[PT_LOAD_OFFSET].tableSize, loadImitate[PT_LOAD_OFFSET].tableSize);
78800b99b8Sopenharmony_ci    ASSERT_EQ(load[PT_LOAD_OFFSET].tableVaddr, loadImitate[PT_LOAD_OFFSET].tableVaddr);
79800b99b8Sopenharmony_ci
80800b99b8Sopenharmony_ci    ASSERT_EQ(elf.GetClassType(), elfImitate.GetClassType());
81800b99b8Sopenharmony_ci    ASSERT_EQ(elf.GetLoadBase(0xf78c0000, 0), elfImitate.GetLoadBase(0xf78c0000, 0));
82800b99b8Sopenharmony_ci    ASSERT_EQ(elf.GetStartPc(), elfImitate.GetStartPc());
83800b99b8Sopenharmony_ci    ASSERT_EQ(elf.GetEndPc(), elfImitate.GetEndPc());
84800b99b8Sopenharmony_ci    ASSERT_EQ(elf.GetRelPc(0xf78c00f0, 0xf78c0000, 0), elfImitate.GetRelPc(0xf78c00f0, 0xf78c0000, 0));
85800b99b8Sopenharmony_ci    ASSERT_EQ(elf.GetBuildId(), "8e5a30338be326934ff93c998dcd0d22fe345870");
86800b99b8Sopenharmony_ci    EXPECT_NE(DfxElf::Create(ELF32_FILE), nullptr);
87800b99b8Sopenharmony_ci    EXPECT_NE(elf.GetGlobalPointer(), 0);
88800b99b8Sopenharmony_ci    EXPECT_FALSE(elf.GetElfSymbols().empty());
89800b99b8Sopenharmony_ci    EXPECT_GT(elf.GetMmapSize(), 0);
90800b99b8Sopenharmony_ci    GTEST_LOG_(INFO) << "DfxElfTest001: end.";
91800b99b8Sopenharmony_ci}
92800b99b8Sopenharmony_ci
93800b99b8Sopenharmony_ci/**
94800b99b8Sopenharmony_ci * @tc.name: DfxElfTest002
95800b99b8Sopenharmony_ci * @tc.desc: test DfxElf functions with 64 bit ELF
96800b99b8Sopenharmony_ci * @tc.type: FUNC
97800b99b8Sopenharmony_ci */
98800b99b8Sopenharmony_ciHWTEST_F(DfxElfTest, DfxElfTest002, TestSize.Level2)
99800b99b8Sopenharmony_ci{
100800b99b8Sopenharmony_ci    GTEST_LOG_(INFO) << "DfxElfTest002: start.";
101800b99b8Sopenharmony_ci    DfxElf elf(ELF64_FILE);
102800b99b8Sopenharmony_ci    ASSERT_TRUE(elf.IsValid());
103800b99b8Sopenharmony_ci    ElfImitate elfImitate;
104800b99b8Sopenharmony_ci    ShdrInfo shdr;
105800b99b8Sopenharmony_ci    ShdrInfo shdrImitate;
106800b99b8Sopenharmony_ci    bool ret = elfImitate.ParseAllHeaders(ElfImitate::ElfFileType::ELF64);
107800b99b8Sopenharmony_ci    ASSERT_TRUE(ret);
108800b99b8Sopenharmony_ci    for (size_t i = 0; i < interestedSections.size(); i++) {
109800b99b8Sopenharmony_ci        GTEST_LOG_(INFO) << interestedSections[i];
110800b99b8Sopenharmony_ci        elf.GetSectionInfo(shdr, interestedSections[i]);
111800b99b8Sopenharmony_ci        elfImitate.GetSectionInfo(shdrImitate, interestedSections[i]);
112800b99b8Sopenharmony_ci        ASSERT_EQ(shdr.addr, shdrImitate.addr);
113800b99b8Sopenharmony_ci        ASSERT_EQ(shdr.offset, shdrImitate.offset);
114800b99b8Sopenharmony_ci        ASSERT_EQ(shdr.size, shdrImitate.size);
115800b99b8Sopenharmony_ci    }
116800b99b8Sopenharmony_ci    ASSERT_EQ(elf.GetArchType(), elfImitate.GetArchType());
117800b99b8Sopenharmony_ci    ASSERT_EQ(elf.GetElfSize(), elfImitate.GetElfSize());
118800b99b8Sopenharmony_ci    ASSERT_EQ(elf.GetLoadBias(), elfImitate.GetLoadBias());
119800b99b8Sopenharmony_ci
120800b99b8Sopenharmony_ci    auto load = elf.GetPtLoads();
121800b99b8Sopenharmony_ci    auto loadImitate = elfImitate.GetPtLoads();
122800b99b8Sopenharmony_ci    ASSERT_EQ(load[PT_LOAD_OFFSET64].offset, loadImitate[PT_LOAD_OFFSET64].offset);
123800b99b8Sopenharmony_ci    ASSERT_EQ(load[PT_LOAD_OFFSET64].tableSize, loadImitate[PT_LOAD_OFFSET64].tableSize);
124800b99b8Sopenharmony_ci    ASSERT_EQ(load[PT_LOAD_OFFSET64].tableVaddr, loadImitate[PT_LOAD_OFFSET64].tableVaddr);
125800b99b8Sopenharmony_ci
126800b99b8Sopenharmony_ci    ASSERT_EQ(elf.GetClassType(), elfImitate.GetClassType());
127800b99b8Sopenharmony_ci    ASSERT_EQ(elf.GetLoadBase(0xf78c0000, 0), elfImitate.GetLoadBase(0xf78c0000, 0));
128800b99b8Sopenharmony_ci    ASSERT_EQ(elf.GetStartPc(), elfImitate.GetStartPc());
129800b99b8Sopenharmony_ci    ASSERT_EQ(elf.GetEndPc(), elfImitate.GetEndPc());
130800b99b8Sopenharmony_ci    ASSERT_EQ(elf.GetRelPc(0xf78c00f0, 0xf78c0000, 0), elfImitate.GetRelPc(0xf78c00f0, 0xf78c0000, 0));
131800b99b8Sopenharmony_ci    ASSERT_EQ(elf.GetBuildId(), "24c55dccc5baaaa140da0083207abcb8d523e248");
132800b99b8Sopenharmony_ci    EXPECT_NE(elf.GetGlobalPointer(), 0);
133800b99b8Sopenharmony_ci    EXPECT_FALSE(elf.GetElfSymbols().empty());
134800b99b8Sopenharmony_ci    EXPECT_GT(elf.GetMmapSize(), 0);
135800b99b8Sopenharmony_ci    GTEST_LOG_(INFO) << "DfxElfTest002: end.";
136800b99b8Sopenharmony_ci}
137800b99b8Sopenharmony_ci
138800b99b8Sopenharmony_ci/**
139800b99b8Sopenharmony_ci * @tc.name: DfxElfTest003
140800b99b8Sopenharmony_ci * @tc.desc: test DfxElf functions with using error
141800b99b8Sopenharmony_ci * @tc.type: FUNC
142800b99b8Sopenharmony_ci */
143800b99b8Sopenharmony_ciHWTEST_F(DfxElfTest, DfxElfTest003, TestSize.Level2)
144800b99b8Sopenharmony_ci{
145800b99b8Sopenharmony_ci    GTEST_LOG_(INFO) << "DfxElfTest003: start.";
146800b99b8Sopenharmony_ci    DfxElf elf("");
147800b99b8Sopenharmony_ci    ASSERT_FALSE(elf.IsValid());
148800b99b8Sopenharmony_ci    ASSERT_EQ(elf.GetClassType(), ELFCLASSNONE);
149800b99b8Sopenharmony_ci    ASSERT_EQ(elf.GetElfSize(), 0);
150800b99b8Sopenharmony_ci    ASSERT_TRUE(elf.GetBuildId().empty());
151800b99b8Sopenharmony_ci    EXPECT_EQ(DfxElf::Create("123"), nullptr);
152800b99b8Sopenharmony_ci    ASSERT_TRUE(DfxElf::ToReadableBuildId("").empty());
153800b99b8Sopenharmony_ci    EXPECT_EQ(elf.GetGlobalPointer(), 0);
154800b99b8Sopenharmony_ci    ShdrInfo shdrInfo;
155800b99b8Sopenharmony_ci    EXPECT_FALSE(elf.GetSectionInfo(shdrInfo, ""));
156800b99b8Sopenharmony_ci    EXPECT_EQ(elf.GetMmapSize(), 0);
157800b99b8Sopenharmony_ci    GTEST_LOG_(INFO) << "DfxElfTest003: end.";
158800b99b8Sopenharmony_ci}
159800b99b8Sopenharmony_ci
160800b99b8Sopenharmony_ci/**
161800b99b8Sopenharmony_ci * @tc.name: DfxElfTest004
162800b99b8Sopenharmony_ci * @tc.desc: test DfxElf class functions with minidebugInfo
163800b99b8Sopenharmony_ci * @tc.type: FUNC
164800b99b8Sopenharmony_ci */
165800b99b8Sopenharmony_ciHWTEST_F(DfxElfTest, DfxElfTest004, TestSize.Level2)
166800b99b8Sopenharmony_ci{
167800b99b8Sopenharmony_ci    GTEST_LOG_(INFO) << "DfxElfTest004: start.";
168800b99b8Sopenharmony_ci    UnwinderConfig::SetEnableMiniDebugInfo(true);
169800b99b8Sopenharmony_ci    DfxElf elf(DUMPCATCHER_ELF_FILE);
170800b99b8Sopenharmony_ci    ASSERT_TRUE(elf.IsValid());
171800b99b8Sopenharmony_ci    ASSERT_TRUE(elf.IsEmbeddedElfValid());
172800b99b8Sopenharmony_ci    auto symbols1 = elf.GetFuncSymbols();
173800b99b8Sopenharmony_ci    GTEST_LOG_(INFO) << "DfxElfTest004: symbols1 size:" << symbols1.size();
174800b99b8Sopenharmony_ci    auto symbols2 = elf.GetEmbeddedElf()->GetFuncSymbols();
175800b99b8Sopenharmony_ci    GTEST_LOG_(INFO) << "DfxElfTest004: symbols2 size:" << symbols2.size();
176800b99b8Sopenharmony_ci    ASSERT_GE(symbols2.size(), 0);
177800b99b8Sopenharmony_ci    ASSERT_GE(symbols1.size(), symbols2.size());
178800b99b8Sopenharmony_ci    GTEST_LOG_(INFO) << "DfxElfTest004: end.";
179800b99b8Sopenharmony_ci}
180800b99b8Sopenharmony_ci
181800b99b8Sopenharmony_ci/**
182800b99b8Sopenharmony_ci * @tc.name: DfxElfTest005
183800b99b8Sopenharmony_ci * @tc.desc: test GetBuildId function when input empty elf file path
184800b99b8Sopenharmony_ci * @tc.type: FUNC
185800b99b8Sopenharmony_ci */
186800b99b8Sopenharmony_ciHWTEST_F(DfxElfTest, DfxElfTest005, TestSize.Level2)
187800b99b8Sopenharmony_ci{
188800b99b8Sopenharmony_ci    auto elfFile = std::make_shared<DfxElf>("");
189800b99b8Sopenharmony_ci    ASSERT_NE(elfFile, nullptr);
190800b99b8Sopenharmony_ci    EXPECT_STREQ(elfFile->GetBuildId().c_str(), "");
191800b99b8Sopenharmony_ci}
192800b99b8Sopenharmony_ci
193800b99b8Sopenharmony_ci/**
194800b99b8Sopenharmony_ci * @tc.name: DfxElfTest006
195800b99b8Sopenharmony_ci * @tc.desc: test GetBuildId function when input illegal elf file path
196800b99b8Sopenharmony_ci * @tc.type: FUNC
197800b99b8Sopenharmony_ci */
198800b99b8Sopenharmony_ciHWTEST_F(DfxElfTest, DfxElfTest006, TestSize.Level2)
199800b99b8Sopenharmony_ci{
200800b99b8Sopenharmony_ci    auto elfFile = std::make_shared<DfxElf>("/proc/illegal");
201800b99b8Sopenharmony_ci    ASSERT_NE(elfFile, nullptr);
202800b99b8Sopenharmony_ci    EXPECT_STREQ(elfFile->GetBuildId().c_str(), "");
203800b99b8Sopenharmony_ci}
204800b99b8Sopenharmony_ci
205800b99b8Sopenharmony_ci/**
206800b99b8Sopenharmony_ci * @tc.name: DfxElfTest007
207800b99b8Sopenharmony_ci * @tc.desc: test SetBaseOffset function and GetBaseOffset function
208800b99b8Sopenharmony_ci * @tc.type: FUNC
209800b99b8Sopenharmony_ci */
210800b99b8Sopenharmony_ciHWTEST_F(DfxElfTest, DfxElfTest007, TestSize.Level2)
211800b99b8Sopenharmony_ci{
212800b99b8Sopenharmony_ci    auto elf = std::make_shared<DfxElf>("");
213800b99b8Sopenharmony_ci    ASSERT_EQ(elf->GetBaseOffset(), 0);
214800b99b8Sopenharmony_ci    elf->SetBaseOffset(1);
215800b99b8Sopenharmony_ci    ASSERT_EQ(elf->GetBaseOffset(), 1);
216800b99b8Sopenharmony_ci}
217800b99b8Sopenharmony_ci} // namespace HiviewDFX
218800b99b8Sopenharmony_ci} // namespace OHOS
219800b99b8Sopenharmony_ci
220