1 /* 2 * Copyright (c) 2022 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 <gtest/gtest.h> 17 #include <ctime> 18 #include <securec.h> 19 #include <string> 20 #include <vector> 21 #include <iostream> 22 #include "dfx_elf.h" 23 #include "elf_imitate.h" 24 #include "unwinder_config.h" 25 26 using namespace OHOS::HiviewDFX; 27 using namespace testing::ext; 28 using namespace std; 29 30 #define ELF32_FILE "/data/test/resource/testdata/elf32_test" 31 #define ELF64_FILE "/data/test/resource/testdata/elf_test" 32 #define DUMPCATCHER_ELF_FILE "/system/bin/dumpcatcher" 33 #define PT_LOAD_OFFSET 0x001000 34 #define PT_LOAD_OFFSET64 0x0000000000002000 35 36 namespace OHOS { 37 namespace HiviewDFX { 38 class DfxElfTest : public testing::Test { 39 public: SetUpTestCase(void)40 static void SetUpTestCase(void) {} TearDownTestCase(void)41 static void TearDownTestCase(void) {} SetUp()42 void SetUp() {} TearDown()43 void TearDown() {} 44 }; 45 46 std::vector<std::string> interestedSections = { ".dynsym", ".eh_frame_hdr", ".eh_frame", ".symtab" }; 47 /** 48 * @tc.name: DfxElfTest001 49 * @tc.desc: test DfxElf functions with 32 bit ELF 50 * @tc.type: FUNC 51 */ 52 HWTEST_F(DfxElfTest, DfxElfTest001, TestSize.Level2) 53 { 54 GTEST_LOG_(INFO) << "DfxElfTest001: start."; 55 DfxElf elf(ELF32_FILE); 56 ASSERT_TRUE(elf.IsValid()); 57 ElfImitate elfImitate; 58 ShdrInfo shdr; 59 ShdrInfo shdrImitate; 60 bool ret = elfImitate.ParseAllHeaders(ElfImitate::ElfFileType::ELF32); 61 ASSERT_TRUE(ret); 62 for (size_t i = 0; i < interestedSections.size(); i++) { 63 elf.GetSectionInfo(shdr, interestedSections[i]); 64 elfImitate.GetSectionInfo(shdrImitate, interestedSections[i]); 65 GTEST_LOG_(INFO) << interestedSections[i]; 66 ASSERT_EQ(shdr.addr, shdrImitate.addr); 67 ASSERT_EQ(shdr.offset, shdrImitate.offset); 68 ASSERT_EQ(shdr.size, shdrImitate.size); 69 } 70 ASSERT_EQ(elf.GetArchType(), elfImitate.GetArchType()); 71 ASSERT_EQ(elf.GetElfSize(), elfImitate.GetElfSize()); 72 ASSERT_EQ(elf.GetLoadBias(), elfImitate.GetLoadBias()); 73 74 auto load = elf.GetPtLoads(); 75 auto loadImitate = elfImitate.GetPtLoads(); 76 ASSERT_EQ(load[PT_LOAD_OFFSET].offset, loadImitate[PT_LOAD_OFFSET].offset); 77 ASSERT_EQ(load[PT_LOAD_OFFSET].tableSize, loadImitate[PT_LOAD_OFFSET].tableSize); 78 ASSERT_EQ(load[PT_LOAD_OFFSET].tableVaddr, loadImitate[PT_LOAD_OFFSET].tableVaddr); 79 80 ASSERT_EQ(elf.GetClassType(), elfImitate.GetClassType()); 81 ASSERT_EQ(elf.GetLoadBase(0xf78c0000, 0), elfImitate.GetLoadBase(0xf78c0000, 0)); 82 ASSERT_EQ(elf.GetStartPc(), elfImitate.GetStartPc()); 83 ASSERT_EQ(elf.GetEndPc(), elfImitate.GetEndPc()); 84 ASSERT_EQ(elf.GetRelPc(0xf78c00f0, 0xf78c0000, 0), elfImitate.GetRelPc(0xf78c00f0, 0xf78c0000, 0)); 85 ASSERT_EQ(elf.GetBuildId(), "8e5a30338be326934ff93c998dcd0d22fe345870"); 86 EXPECT_NE(DfxElf::Create(ELF32_FILE), nullptr); 87 EXPECT_NE(elf.GetGlobalPointer(), 0); 88 EXPECT_FALSE(elf.GetElfSymbols().empty()); 89 EXPECT_GT(elf.GetMmapSize(), 0); 90 GTEST_LOG_(INFO) << "DfxElfTest001: end."; 91 } 92 93 /** 94 * @tc.name: DfxElfTest002 95 * @tc.desc: test DfxElf functions with 64 bit ELF 96 * @tc.type: FUNC 97 */ 98 HWTEST_F(DfxElfTest, DfxElfTest002, TestSize.Level2) 99 { 100 GTEST_LOG_(INFO) << "DfxElfTest002: start."; 101 DfxElf elf(ELF64_FILE); 102 ASSERT_TRUE(elf.IsValid()); 103 ElfImitate elfImitate; 104 ShdrInfo shdr; 105 ShdrInfo shdrImitate; 106 bool ret = elfImitate.ParseAllHeaders(ElfImitate::ElfFileType::ELF64); 107 ASSERT_TRUE(ret); 108 for (size_t i = 0; i < interestedSections.size(); i++) { 109 GTEST_LOG_(INFO) << interestedSections[i]; 110 elf.GetSectionInfo(shdr, interestedSections[i]); 111 elfImitate.GetSectionInfo(shdrImitate, interestedSections[i]); 112 ASSERT_EQ(shdr.addr, shdrImitate.addr); 113 ASSERT_EQ(shdr.offset, shdrImitate.offset); 114 ASSERT_EQ(shdr.size, shdrImitate.size); 115 } 116 ASSERT_EQ(elf.GetArchType(), elfImitate.GetArchType()); 117 ASSERT_EQ(elf.GetElfSize(), elfImitate.GetElfSize()); 118 ASSERT_EQ(elf.GetLoadBias(), elfImitate.GetLoadBias()); 119 120 auto load = elf.GetPtLoads(); 121 auto loadImitate = elfImitate.GetPtLoads(); 122 ASSERT_EQ(load[PT_LOAD_OFFSET64].offset, loadImitate[PT_LOAD_OFFSET64].offset); 123 ASSERT_EQ(load[PT_LOAD_OFFSET64].tableSize, loadImitate[PT_LOAD_OFFSET64].tableSize); 124 ASSERT_EQ(load[PT_LOAD_OFFSET64].tableVaddr, loadImitate[PT_LOAD_OFFSET64].tableVaddr); 125 126 ASSERT_EQ(elf.GetClassType(), elfImitate.GetClassType()); 127 ASSERT_EQ(elf.GetLoadBase(0xf78c0000, 0), elfImitate.GetLoadBase(0xf78c0000, 0)); 128 ASSERT_EQ(elf.GetStartPc(), elfImitate.GetStartPc()); 129 ASSERT_EQ(elf.GetEndPc(), elfImitate.GetEndPc()); 130 ASSERT_EQ(elf.GetRelPc(0xf78c00f0, 0xf78c0000, 0), elfImitate.GetRelPc(0xf78c00f0, 0xf78c0000, 0)); 131 ASSERT_EQ(elf.GetBuildId(), "24c55dccc5baaaa140da0083207abcb8d523e248"); 132 EXPECT_NE(elf.GetGlobalPointer(), 0); 133 EXPECT_FALSE(elf.GetElfSymbols().empty()); 134 EXPECT_GT(elf.GetMmapSize(), 0); 135 GTEST_LOG_(INFO) << "DfxElfTest002: end."; 136 } 137 138 /** 139 * @tc.name: DfxElfTest003 140 * @tc.desc: test DfxElf functions with using error 141 * @tc.type: FUNC 142 */ 143 HWTEST_F(DfxElfTest, DfxElfTest003, TestSize.Level2) 144 { 145 GTEST_LOG_(INFO) << "DfxElfTest003: start."; 146 DfxElf elf(""); 147 ASSERT_FALSE(elf.IsValid()); 148 ASSERT_EQ(elf.GetClassType(), ELFCLASSNONE); 149 ASSERT_EQ(elf.GetElfSize(), 0); 150 ASSERT_TRUE(elf.GetBuildId().empty()); 151 EXPECT_EQ(DfxElf::Create("123"), nullptr); 152 ASSERT_TRUE(DfxElf::ToReadableBuildId("").empty()); 153 EXPECT_EQ(elf.GetGlobalPointer(), 0); 154 ShdrInfo shdrInfo; 155 EXPECT_FALSE(elf.GetSectionInfo(shdrInfo, "")); 156 EXPECT_EQ(elf.GetMmapSize(), 0); 157 GTEST_LOG_(INFO) << "DfxElfTest003: end."; 158 } 159 160 /** 161 * @tc.name: DfxElfTest004 162 * @tc.desc: test DfxElf class functions with minidebugInfo 163 * @tc.type: FUNC 164 */ 165 HWTEST_F(DfxElfTest, DfxElfTest004, TestSize.Level2) 166 { 167 GTEST_LOG_(INFO) << "DfxElfTest004: start."; 168 UnwinderConfig::SetEnableMiniDebugInfo(true); 169 DfxElf elf(DUMPCATCHER_ELF_FILE); 170 ASSERT_TRUE(elf.IsValid()); 171 ASSERT_TRUE(elf.IsEmbeddedElfValid()); 172 auto symbols1 = elf.GetFuncSymbols(); 173 GTEST_LOG_(INFO) << "DfxElfTest004: symbols1 size:" << symbols1.size(); 174 auto symbols2 = elf.GetEmbeddedElf()->GetFuncSymbols(); 175 GTEST_LOG_(INFO) << "DfxElfTest004: symbols2 size:" << symbols2.size(); 176 ASSERT_GE(symbols2.size(), 0); 177 ASSERT_GE(symbols1.size(), symbols2.size()); 178 GTEST_LOG_(INFO) << "DfxElfTest004: end."; 179 } 180 181 /** 182 * @tc.name: DfxElfTest005 183 * @tc.desc: test GetBuildId function when input empty elf file path 184 * @tc.type: FUNC 185 */ 186 HWTEST_F(DfxElfTest, DfxElfTest005, TestSize.Level2) 187 { 188 auto elfFile = std::make_shared<DfxElf>(""); 189 ASSERT_NE(elfFile, nullptr); 190 EXPECT_STREQ(elfFile->GetBuildId().c_str(), ""); 191 } 192 193 /** 194 * @tc.name: DfxElfTest006 195 * @tc.desc: test GetBuildId function when input illegal elf file path 196 * @tc.type: FUNC 197 */ 198 HWTEST_F(DfxElfTest, DfxElfTest006, TestSize.Level2) 199 { 200 auto elfFile = std::make_shared<DfxElf>("/proc/illegal"); 201 ASSERT_NE(elfFile, nullptr); 202 EXPECT_STREQ(elfFile->GetBuildId().c_str(), ""); 203 } 204 205 /** 206 * @tc.name: DfxElfTest007 207 * @tc.desc: test SetBaseOffset function and GetBaseOffset function 208 * @tc.type: FUNC 209 */ 210 HWTEST_F(DfxElfTest, DfxElfTest007, TestSize.Level2) 211 { 212 auto elf = std::make_shared<DfxElf>(""); 213 ASSERT_EQ(elf->GetBaseOffset(), 0); 214 elf->SetBaseOffset(1); 215 ASSERT_EQ(elf->GetBaseOffset(), 1); 216 } 217 } // namespace HiviewDFX 218 } // namespace OHOS 219 220