• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-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 "symbols_file_test.h"
17 
18 #include <gmock/gmock.h>
19 #include <gtest/gtest.h>
20 #include <hilog/log.h>
21 #include <random>
22 #include <unistd.h>
23 
24 using namespace testing::ext;
25 
26 namespace OHOS {
27 namespace Developtools {
28 namespace HiPerf {
29 class SymbolsFileTest : public testing::Test {
30 public:
31     static void SetUpTestCase(void);
32     static void TearDownTestCase(void);
33     void SetUp();
34     void TearDown();
35     void CheckSymbols(const std::unique_ptr<SymbolsFile> &symbolsFile) const;
36     void PrintSymbols(const std::vector<DfxSymbol> &symbol) const;
37     bool KptrRestrict() const;
38 
LoadSymbols(SymbolsFileType symbolsFileType)39     std::unique_ptr<SymbolsFile> LoadSymbols(SymbolsFileType symbolsFileType)
40     {
41         std::unique_ptr<SymbolsFile> symbolsFile = SymbolsFile::CreateSymbolsFile(symbolsFileType);
42         EXPECT_EQ(symbolsFile->setSymbolsFilePath(PATH_RESOURCE_TEST_DATA), true);
43         return symbolsFile;
44     }
45 
TestLoadSymbols(SymbolsFileType symbolsFileType,const std::string & path)46     bool TestLoadSymbols(SymbolsFileType symbolsFileType, const std::string &path)
47     {
48         std::unique_ptr<SymbolsFile> symbolsFile = SymbolsFile::CreateSymbolsFile(symbolsFileType);
49         EXPECT_EQ(symbolsFile->setSymbolsFilePath(PATH_RESOURCE_TEST_DATA), true);
50         return symbolsFile->LoadSymbols(nullptr, path);
51     }
52     std::default_random_engine rnd_;
53 };
54 
SetUpTestCase()55 void SymbolsFileTest::SetUpTestCase() {}
56 
TearDownTestCase()57 void SymbolsFileTest::TearDownTestCase() {}
58 
SetUp()59 void SymbolsFileTest::SetUp() {}
60 
TearDown()61 void SymbolsFileTest::TearDown() {}
62 
KptrRestrict() const63 bool SymbolsFileTest::KptrRestrict() const
64 {
65     std::ifstream inputString(KPTR_RESTRICT, std::ios::in);
66     if (inputString) {
67         string kptrRestrict = "1";
68         inputString >> kptrRestrict;
69         if (kptrRestrict == "0") {
70             return false;
71         }
72     }
73     return true;
74 }
75 
CheckSymbols(const std::unique_ptr<SymbolsFile> & symbolsFile) const76 void SymbolsFileTest::CheckSymbols(const std::unique_ptr<SymbolsFile> &symbolsFile) const
77 {
78     auto symbols = symbolsFile->GetSymbols();
79     EXPECT_EQ(symbols.empty(), false);
80     ASSERT_GE(symbols.size(), 1u);
81     PrintSymbols(symbols);
82 
83     // first is 0
84     EXPECT_EQ(symbolsFile->GetSymbolWithVaddr(0x0).funcVaddr_, 0u);
85 
86     // last is IsValid
87     EXPECT_EQ(symbolsFile->GetSymbolWithVaddr(std::numeric_limits<uint64_t>::max()).IsValid(),
88               true);
89 
90     for (uint64_t pos = 0; pos < symbols.size(); ++pos) {
91         uint64_t vaddr = symbols[pos].funcVaddr_;
92         EXPECT_EQ(symbolsFile->GetSymbolWithVaddr(vaddr).funcVaddr_, vaddr);
93     }
94     for (auto symbol : symbols) {
95         if (symbol.name_.find("_Z") != std::string::npos) {
96             EXPECT_NE(symbol.demangle_.find("_Z"), 0u);
97         }
98     }
99 }
100 
PrintSymbols(const std::vector<DfxSymbol> & symbols) const101 void SymbolsFileTest::PrintSymbols(const std::vector<DfxSymbol> &symbols) const
102 {
103     size_t printNumber = 15;
104     if (printNumber > symbols.size())
105         printNumber = symbols.size();
106 
107     printf("first %zu:\n", printNumber);
108     for (size_t i = 0; i < printNumber; i++) {
109         printf("%s\n", symbols[i].ToDebugString().c_str());
110     }
111     if (printNumber < symbols.size()) {
112         printf("last %zu:\n", printNumber);
113         for (size_t i = printNumber; i > 0; i--) {
114             printf("%s\n", symbols[symbols.size() - i].ToDebugString().c_str());
115         }
116     }
117 }
118 
119 /**
120  * @tc.name: setSymbolsFilePath
121  * @tc.desc:
122  * @tc.type: FUNC
123  */
124 HWTEST_F(SymbolsFileTest, setSymbolsFilePath, TestSize.Level2)
125 {
126     auto symbolsFile = SymbolsFile::CreateSymbolsFile(SYMBOL_UNKNOW_FILE);
127     EXPECT_EQ(symbolsFile->setSymbolsFilePath(PATH_DATA_TEMP), true);
128     EXPECT_EQ(symbolsFile->setSymbolsFilePath(PATH_NOT_EXISTS), false);
129     EXPECT_EQ(symbolsFile->setSymbolsFilePath(PATH_DATA_TEMP_WINDOS), false);
130     EXPECT_EQ(symbolsFile->setSymbolsFilePath(PATH_ILLEGAL), false);
131     EXPECT_EQ(symbolsFile->setSymbolsFilePath(PATH_RESOURCE_TEST_DATA), true);
132     EXPECT_EQ(symbolsFile->setSymbolsFilePath(PATH_RESOURCE_TEST_DATA_NO_ENDPATH), true);
133 }
134 
135 /**
136  * @tc.name: setSymbolsFilePath
137  * @tc.desc:
138  * @tc.type: FUNC
139  */
140 HWTEST_F(SymbolsFileTest, setSymbolsFilePathVectorSuccess, TestSize.Level1)
141 {
142     auto symbolsFile = SymbolsFile::CreateSymbolsFile(SYMBOL_UNKNOW_FILE);
143     std::vector<std::string> symbolsSearchPaths;
144 
145     symbolsSearchPaths.clear();
146     symbolsSearchPaths.push_back(PATH_DATA_TEMP);
147     EXPECT_EQ(symbolsFile->setSymbolsFilePath(symbolsSearchPaths), true);
148 
149     symbolsSearchPaths.clear();
150     symbolsSearchPaths.push_back(PATH_DATA_TEMP);
151     symbolsSearchPaths.push_back(PATH_DATA_TEMP);
152     EXPECT_EQ(symbolsFile->setSymbolsFilePath(symbolsSearchPaths), true);
153 
154     symbolsSearchPaths.clear();
155     symbolsSearchPaths.push_back(PATH_DATA_TEMP);
156     symbolsSearchPaths.push_back(PATH_DATA_TEMP);
157     symbolsSearchPaths.push_back(PATH_DATA_TEMP);
158     EXPECT_EQ(symbolsFile->setSymbolsFilePath(symbolsSearchPaths), true);
159 }
160 
161 /**
162  * @tc.name: setSymbolsFilePath
163  * @tc.desc:
164  * @tc.type: FUNC
165  */
166 HWTEST_F(SymbolsFileTest, setSymbolsFilePathVectorFailed, TestSize.Level3)
167 {
168     auto symbolsFile = SymbolsFile::CreateSymbolsFile(SYMBOL_UNKNOW_FILE);
169     std::vector<std::string> symbolsSearchPaths;
170 
171     symbolsSearchPaths.clear();
172     symbolsSearchPaths.push_back(PATH_NOT_EXISTS);
173     EXPECT_EQ(symbolsFile->setSymbolsFilePath(symbolsSearchPaths), false);
174 
175     symbolsSearchPaths.clear();
176     symbolsSearchPaths.push_back(PATH_NOT_EXISTS);
177     symbolsSearchPaths.push_back(PATH_NOT_EXISTS);
178     EXPECT_EQ(symbolsFile->setSymbolsFilePath(symbolsSearchPaths), false);
179 
180     symbolsSearchPaths.clear();
181     symbolsSearchPaths.push_back(PATH_NOT_EXISTS);
182     symbolsSearchPaths.push_back(PATH_NOT_EXISTS);
183     symbolsSearchPaths.push_back(PATH_NOT_EXISTS);
184     EXPECT_EQ(symbolsFile->setSymbolsFilePath(symbolsSearchPaths), false);
185 }
186 
187 /**
188  * @tc.name: setSymbolsFilePath
189  * @tc.desc:
190  * @tc.type: FUNC
191  */
192 HWTEST_F(SymbolsFileTest, setSymbolsFilePathVectorMixSucessed, TestSize.Level1)
193 {
194     auto symbolsFile = SymbolsFile::CreateSymbolsFile(SYMBOL_UNKNOW_FILE);
195     std::vector<std::string> symbolsSearchPaths;
196 
197     symbolsSearchPaths.clear();
198     symbolsSearchPaths.push_back(PATH_DATA_TEMP);
199     symbolsSearchPaths.push_back(PATH_NOT_EXISTS);
200     EXPECT_EQ(symbolsFile->setSymbolsFilePath(symbolsSearchPaths), true);
201 
202     symbolsSearchPaths.clear();
203     symbolsSearchPaths.push_back(PATH_DATA_TEMP);
204     symbolsSearchPaths.push_back(PATH_NOT_EXISTS);
205     symbolsSearchPaths.push_back(PATH_DATA_TEMP);
206     symbolsSearchPaths.push_back(PATH_NOT_EXISTS);
207     EXPECT_EQ(symbolsFile->setSymbolsFilePath(symbolsSearchPaths), true);
208 
209     symbolsSearchPaths.clear();
210     symbolsSearchPaths.push_back(PATH_DATA_TEMP);
211     symbolsSearchPaths.push_back(PATH_NOT_EXISTS);
212     symbolsSearchPaths.push_back(PATH_DATA_TEMP);
213     symbolsSearchPaths.push_back(PATH_NOT_EXISTS);
214     symbolsSearchPaths.push_back(PATH_DATA_TEMP);
215     symbolsSearchPaths.push_back(PATH_NOT_EXISTS);
216     EXPECT_EQ(symbolsFile->setSymbolsFilePath(symbolsSearchPaths), true);
217 }
218 
TestLoadSymbols(SymbolsFileType symbolsFileType,const std::string & path)219 bool TestLoadSymbols(SymbolsFileType symbolsFileType, const std::string &path)
220 {
221     std::unique_ptr<SymbolsFile> symbolsFile = SymbolsFile::CreateSymbolsFile(symbolsFileType);
222     EXPECT_EQ(symbolsFile->setSymbolsFilePath(PATH_RESOURCE_TEST_DATA), true);
223     return symbolsFile->LoadSymbols(nullptr, path);
224 }
225 
226 /**
227  * @tc.name: SymbolsFile Default Virtual
228  * @tc.desc:
229  * @tc.type: FUNC
230  */
231 HWTEST_F(SymbolsFileTest, SymbolsFileDefaultVirtual, TestSize.Level2)
232 {
233     std::unique_ptr<SymbolsFile> symbolsFile = SymbolsFile::CreateSymbolsFile(SYMBOL_UNKNOW_FILE);
234     uint64_t value = 0;
235     ASSERT_EQ(symbolsFile->LoadDebugInfo(), false);
236     EXPECT_EQ(symbolsFile->GetSectionInfo("", value, value, value), false);
237 #ifndef __arm__
238     EXPECT_EQ(symbolsFile->GetHDRSectionInfo(value, value, value), false);
239 #endif
240 }
241 
242 /**
243  * @tc.name: LoaderKernelSymbols
244  * @tc.desc:
245  * @tc.type: FUNC
246  */
247 HWTEST_F(SymbolsFileTest, LoadKernelSymbols, TestSize.Level0)
248 {
249     if (access("/sys/kernel/notes", F_OK) == 0) {
250         // read from kernel runtime
251         std::unique_ptr<SymbolsFile> symbolsFile = SymbolsFile::CreateSymbolsFile(SYMBOL_KERNEL_FILE);
252         ScopeDebugLevel tempLogLevel(LEVEL_VERBOSE);
253         ASSERT_EQ(symbolsFile->LoadSymbols(), true);
254 
255         const std::vector<DfxSymbol> &symbols = symbolsFile->GetSymbols();
256         EXPECT_EQ(symbols.empty(), false);
257 
258         std::string modulesMap = ReadFileToString("/proc/modules");
259         int lines = std::count(modulesMap.begin(), modulesMap.end(), '\n');
260         if (lines >= 0) {
261             std::set<std::string> modulesCount;
262             for (auto &symbol : symbols) {
263                 if (symbol.module_.length()) {
264                     modulesCount.emplace(symbol.module_);
265                 }
266             }
267 
268             // add [kernel.kallsyms]
269             if (modulesCount.size() != lines + 1u) {
270                 printf("warn: modulesCount != lines + 1\n");
271             }
272             if (HasFailure()) {
273                 for (auto &module : modulesCount) {
274                     printf("%s\n", module.c_str());
275                 }
276             }
277 
278             // try vmlinux
279             EXPECT_EQ(TestLoadSymbols(SYMBOL_KERNEL_FILE, TEST_FILE_VMLINUX), true);
280             EXPECT_EQ(TestLoadSymbols(SYMBOL_KERNEL_FILE, TEST_FILE_VMLINUX_STRIPPED), true);
281             EXPECT_EQ(TestLoadSymbols(SYMBOL_KERNEL_FILE, TEST_FILE_VMLINUX_STRIPPED_NOBUILDID), true);
282             // will be load from runtime, still return true
283             EXPECT_EQ(TestLoadSymbols(SYMBOL_KERNEL_FILE, TEST_FILE_VMLINUX_STRIPPED_BROKEN), true);
284         }
285     } else {
286         printf("cannot access /sys/kernel/notes\n");
287     }
288 }
289 
290 /**
291  * @tc.name: LoaderElfSymbols
292  * @tc.desc:
293  * @tc.type: FUNC
294  */
295 HWTEST_F(SymbolsFileTest, LoadElfSymbols, TestSize.Level1)
296 {
297     auto symbolsElfLoader = SymbolsFile::CreateSymbolsFile(SYMBOL_ELF_FILE);
298     auto symbolsElfStrippedLoader = SymbolsFile::CreateSymbolsFile(SYMBOL_ELF_FILE);
299     ScopeDebugLevel tempLogLevel(LEVEL_VERBOSE);
300 
301     EXPECT_EQ(symbolsElfLoader->LoadSymbols(), false);
302 
303     ASSERT_EQ(symbolsElfLoader->setSymbolsFilePath(PATH_RESOURCE_TEST_DATA), true);
304     EXPECT_EQ(symbolsElfLoader->LoadSymbols(nullptr, TEST_FILE_ELF), true);
305     if (HasFailure()) {
306         PrintSymbols(symbolsElfLoader->GetSymbols());
307     }
308 
309     ASSERT_EQ(symbolsElfStrippedLoader->setSymbolsFilePath(PATH_RESOURCE_TEST_DATA), true);
310     EXPECT_EQ(symbolsElfStrippedLoader->LoadSymbols(nullptr, TEST_FILE_ELF_STRIPPED), true);
311     if (HasFailure()) {
312         PrintSymbols(symbolsElfStrippedLoader->GetSymbols());
313     }
314     EXPECT_GT(symbolsElfLoader->GetSymbols().size(), symbolsElfStrippedLoader->GetSymbols().size());
315 
316     ASSERT_EQ(symbolsElfStrippedLoader->setSymbolsFilePath(PATH_RESOURCE_TEST_DATA), true);
317     EXPECT_EQ(symbolsElfStrippedLoader->LoadSymbols(nullptr, TEST_FILE_ELF), true);
318     if (HasFailure()) {
319         PrintSymbols(symbolsElfStrippedLoader->GetSymbols());
320     }
321 
322     // no symbols not means failed.
323     EXPECT_EQ(TestLoadSymbols(SYMBOL_ELF_FILE, TEST_FILE_ELF_STRIPPED), true);
324 
325     // no build id not means failed.
326     EXPECT_EQ(TestLoadSymbols(SYMBOL_ELF_FILE, TEST_FILE_ELF_STRIPPED_NOBUILDID), true);
327 
328     EXPECT_EQ(TestLoadSymbols(SYMBOL_ELF_FILE, TEST_FILE_ELF_STRIPPED_BROKEN), false);
329 }
330 
331 /**
332  * @tc.name: GetSymbolWithVaddr
333  * @tc.desc:
334  * @tc.type: FUNC
335  */
336 HWTEST_F(SymbolsFileTest, GetSymbolWithVaddr, TestSize.Level0)
337 {
338     if (access("/sys/kernel/notes", F_OK) == 0) {
339         auto symbols = SymbolsFile::CreateSymbolsFile(SYMBOL_KERNEL_FILE);
340         if ((0 == getuid())) {
341             HLOGD("in root mode");
342             EXPECT_EQ(symbols->LoadSymbols(), true);
343             CheckSymbols(symbols);
344         } else {
345             EXPECT_EQ(symbols->LoadSymbols(), true);
346             if (!KptrRestrict()) {
347                 HLOGD("NOT KptrRestrict");
348                 if (!symbols->GetSymbols().empty()) {
349                     CheckSymbols(symbols);
350                 } else {
351                     printf("we found this issue in linux-5.10\n");
352                 }
353             } else {
354                 HLOGD("KptrRestrict");
355                 ASSERT_EQ(symbols->GetSymbols().empty(), true);
356             }
357         }
358     } else {
359         printf("cannot access /sys/kernel/notes\n");
360     }
361 }
362 
363 /**
364  * @tc.name: GetSymbolWithVaddr
365  * @tc.desc:
366  * @tc.type: FUNC
367  */
368 HWTEST_F(SymbolsFileTest, GetSymbolWithVaddr2, TestSize.Level1)
369 {
370     auto elfSymbols = SymbolsFile::CreateSymbolsFile(SYMBOL_ELF_FILE);
371     ASSERT_EQ(elfSymbols->setSymbolsFilePath(PATH_RESOURCE_TEST_DATA), true);
372     EXPECT_EQ(elfSymbols->LoadSymbols(nullptr, TEST_FILE_ELF), true);
373     ASSERT_EQ(elfSymbols->GetSymbols().empty(), false);
374 
375     /*
376         part of elf32_test's symbols
377         vaddr(hex)  size(dec)   name
378         00001000    0           _init
379         00001030    0
380         00001320    58           _start
381         00001512    27          main
382         0000145d    124         TestGlobalChildFunction
383         000014d9    57          TestGlobalParentFunction
384         // last one
385         00001b38    0           _fini
386 
387         part of elf_test's symbols
388         vaddr(hex)          size(dec)   name
389         0000000000002000    0           _init
390         0000000000002020    0
391         00000000000022f0    47         _start
392         0000000000002478    15          main
393         00000000000023d9    110         TestGlobalChildFunction
394         0000000000002447    49          TestGlobalParentFunction
395         //last one
396         0000000000002aa8    0           _fini
397     */
398 #ifdef __arm__
399     ScopeDebugLevel tempLogLevel(LEVEL_MUCH, true);
400     EXPECT_EQ(elfSymbols->GetSymbolWithVaddr(0x00001320).GetName(), "_start");
401     EXPECT_EQ(elfSymbols->GetSymbolWithVaddr(0x00001359).GetName(), "_start");
402     EXPECT_EQ(elfSymbols->GetSymbolWithVaddr(0x00001512).GetName(), "main");
403     EXPECT_EQ(elfSymbols->GetSymbolWithVaddr(0x0000152c).GetName(), "main");
404     EXPECT_EQ(elfSymbols->GetSymbolWithVaddr(0x0000145d).GetName(), "TestGlobalChildFunction");
405     EXPECT_EQ(elfSymbols->GetSymbolWithVaddr(0x000014d9).GetName(), "TestGlobalParentFunction");
406 #else
407     EXPECT_EQ(elfSymbols->GetSymbolWithVaddr(0x000022f0).GetName(), "_start");
408     EXPECT_EQ(elfSymbols->GetSymbolWithVaddr(0x0000231e).GetName(), "_start");
409     EXPECT_EQ(elfSymbols->GetSymbolWithVaddr(0x00002478).GetName(), "main");
410     EXPECT_EQ(elfSymbols->GetSymbolWithVaddr(0x00002486).GetName(), "main");
411     EXPECT_EQ(elfSymbols->GetSymbolWithVaddr(0x000023d9).GetName(), "TestGlobalChildFunction");
412     EXPECT_EQ(elfSymbols->GetSymbolWithVaddr(0x00002447).GetName(), "TestGlobalParentFunction");
413 #endif
414     if (HasFailure()) {
415         PrintSymbols(elfSymbols->GetSymbols());
416     }
417 }
418 
419 /**
420  * @tc.name: GetSymbolWithVaddr
421  * @tc.desc:
422  * @tc.type: FUNC
423  */
424 HWTEST_F(SymbolsFileTest, GetSymbolWithVaddrFullMatch, TestSize.Level2)
425 {
426     auto elfSymbols = SymbolsFile::CreateSymbolsFile(SYMBOL_ELF_FILE);
427     ASSERT_EQ(elfSymbols->setSymbolsFilePath(PATH_RESOURCE_TEST_DATA), true);
428     if (elfSymbols->LoadSymbols(nullptr, TEST_SYMBOLS_FILE_ELF)) {
429         ASSERT_EQ(elfSymbols->GetSymbols().empty(), false);
430         /*
431             nm -C --defined-only symbols_file_test_elf64
432             addr = 1000 mangle name = _init
433             addr = 1040 mangle name = _start
434             addr = 1070 mangle name = deregister_tm_clones
435             addr = 10a0 mangle name = register_tm_clones
436             addr = 10e0 mangle name = __do_global_dtors_aux
437             addr = 1120 mangle name = frame_dummy
438             addr = 1129 mangle name = main
439             addr = 1140 mangle name = __libc_csu_init
440             addr = 11b0 mangle name = __libc_csu_fini
441 
442             //last one
443             addr = 11b8 mangle name = _fini
444 
445             nm -C --defined-only symbols_file_test_elf32
446             00001000 t _init
447             00001070 T _start
448             000010c0 t deregister_tm_clones
449             00001100 t register_tm_clones
450             00001150 t __do_global_dtors_aux
451             000011a0 t frame_dummy
452             000011ad T main
453             000011d0 T __libc_csu_init
454             00001240 T __libc_csu_fini
455 
456             // last one
457             0000124c T _fini
458         */
459 #ifdef __arm__
460         enum SymbolAddr : uint64_t {
461             PLT = 0X1030U,
462             START = 0X1070U,
463             THUNK_AX = 0X10B0U,
464             DEREG = 0X10C0U,
465             REG = 0X1100U,
466             AUX = 0X1150U,
467             FRAME = 0X11A0U,
468             THUNK_DX = 0X11A9U,
469             MAIN = 0X11ADU,
470             THUNK_BX = 0X11C5U,
471             CSU_INIT = 0X11D0U,
472             CSU_FINI = 0X1240U,
473             THUNK_BP = 0X1245U,
474         };
475 #else
476         enum SymbolAddr : uint64_t {
477             PLT = 0X1020U,
478             START = 0X1040U,
479             DEREG = 0X1070U,
480             REG = 0X10A0U,
481             AUX = 0X10E0U,
482             FRAME = 0X1120U,
483             MAIN = 0X1129U,
484             CSU_INIT = 0X1140U,
485             CSU_FINI = 0X11B0U,
486         };
487 #endif
488 #ifdef __arm__
489         for (uint64_t addr = SymbolAddr::START; addr < SymbolAddr::THUNK_AX; ++addr) {
490 #else
491         for (uint64_t addr = SymbolAddr::START; addr < SymbolAddr::START; ++addr) {
492 #endif
493             if (elfSymbols->GetSymbolWithVaddr(addr).IsValid()) {
494                 EXPECT_EQ(elfSymbols->GetSymbolWithVaddr(addr).demangle_, "_start");
495             }
496         }
497         for (uint64_t addr = SymbolAddr::DEREG; addr < SymbolAddr::REG; ++addr) {
498             if (elfSymbols->GetSymbolWithVaddr(addr).IsValid()) {
499                 EXPECT_EQ(elfSymbols->GetSymbolWithVaddr(addr).demangle_, "deregister_tm_clones");
500             }
501         }
502         for (uint64_t addr = SymbolAddr::REG; addr < SymbolAddr::AUX; ++addr) {
503             if (elfSymbols->GetSymbolWithVaddr(addr).IsValid()) {
504                 EXPECT_EQ(elfSymbols->GetSymbolWithVaddr(addr).demangle_, "register_tm_clones");
505             }
506         }
507         for (uint64_t addr = SymbolAddr::AUX; addr < SymbolAddr::FRAME; ++addr) {
508             if (elfSymbols->GetSymbolWithVaddr(addr).IsValid()) {
509                 EXPECT_EQ(elfSymbols->GetSymbolWithVaddr(addr).demangle_, "__do_global_dtors_aux");
510             }
511         }
512 #ifdef __arm__
513         for (uint64_t addr = SymbolAddr::FRAME; addr < SymbolAddr::THUNK_DX; ++addr) {
514 #else
515         for (uint64_t addr = SymbolAddr::FRAME; addr < SymbolAddr::MAIN; ++addr) {
516 #endif
517             if (elfSymbols->GetSymbolWithVaddr(addr).IsValid()) {
518                 EXPECT_EQ(elfSymbols->GetSymbolWithVaddr(addr).demangle_, "frame_dummy");
519             }
520         }
521 #ifdef __arm__
522         for (uint64_t addr = SymbolAddr::MAIN; addr < SymbolAddr::THUNK_BX; ++addr) {
523 #else
524         for (uint64_t addr = SymbolAddr::MAIN; addr < SymbolAddr::CSU_INIT; ++addr) {
525 #endif
526             if (elfSymbols->GetSymbolWithVaddr(addr).IsValid()) {
527                 EXPECT_EQ(elfSymbols->GetSymbolWithVaddr(addr).demangle_, "main");
528             }
529         }
530         for (uint64_t addr = SymbolAddr::CSU_INIT; addr < SymbolAddr::CSU_FINI; ++addr) {
531             if (elfSymbols->GetSymbolWithVaddr(addr).IsValid()) {
532                 EXPECT_EQ(elfSymbols->GetSymbolWithVaddr(addr).demangle_, "__libc_csu_init");
533             }
534         }
535         if (HasFailure()) {
536             PrintSymbols(elfSymbols->GetSymbols());
537         }
538     }
539 }
540 
541 /**
542  * @tc.name: GetVaddrInSymbols
543  * @tc.desc:
544  * @tc.type: FUNC
545  */
546 HWTEST_F(SymbolsFileTest, GetVaddrInSymbols, TestSize.Level1)
547 {
548     /*
549         00200000-002c5000 r--p 00000000 08:02 46400311
550         002c5000-00490000 r-xp 000c5000 08:02 4640031
551 
552         [14] .text             PROGBITS         00000000002c5000  000c5000
553 
554         if ip is 0x46e6ab
555         1. find the map range is 002c5000-00490000
556         2. ip - map start(002c5000) = map section offset
557         3. map section offset + map page offset(000c5000) = elf file offset
558         4. elf file offset - exec file offset(000c5000)
559             = ip offset (ip always in exec file offset)
560         5. ip offset + exec begin vaddr(2c5000) = virtual ip in elf
561     */
562     auto elfSymbols = SymbolsFile::CreateSymbolsFile(SYMBOL_ELF_FILE);
563     elfSymbols->textExecVaddrFileOffset_ = 0x000c5000;
564     elfSymbols->textExecVaddr_ = 0x002c5000;
565 
566     // most easy case
567     EXPECT_EQ(elfSymbols->GetVaddrInSymbols(0x002c5123, 0x002c5000, 0x000c5000), 0x002c5123U);
568 
569     // ip and map both change
570     EXPECT_EQ(elfSymbols->GetVaddrInSymbols(0xFF2c5123, 0xFF2c5000, 0x000c5000), 0x002c5123U);
571     EXPECT_EQ(elfSymbols->GetVaddrInSymbols(0x00000123, 0x00000000, 0x000c5000), 0x002c5123U);
572 
573     // map page and offset change
574     EXPECT_EQ(elfSymbols->GetVaddrInSymbols(0x002ca123, 0x002c5000, 0x000c0000), 0x002c5123U);
575     EXPECT_EQ(elfSymbols->GetVaddrInSymbols(0x002c4123, 0x002c5000, 0x000c6000), 0x002c5123U);
576 
577     // kernel dont care offset
578     auto kernelSymbols = SymbolsFile::CreateSymbolsFile(SYMBOL_KERNEL_FILE);
579     EXPECT_EQ(kernelSymbols->GetVaddrInSymbols(0x001234, 0x002c5000, 0x000c5000), 0x001234U);
580 }
581 
582 /**
583  * @tc.name: FindSymbolFile
584  * @tc.desc:
585  * @tc.type: FUNC
586  */
587 HWTEST_F(SymbolsFileTest, FindSymbolFile, TestSize.Level1)
588 {
589     auto symbols = SymbolsFile::CreateSymbolsFile(SYMBOL_ELF_FILE);
590 
591     std::vector<std::string> symbolsFileSearchPaths;
592     std::string symboleFilePath;
593 
594     symboleFilePath = TEST_FILE_VMLINUX;
595     EXPECT_EQ(symbols->FindSymbolFile(symbolsFileSearchPaths, symboleFilePath).empty(), true);
596 
597     symbolsFileSearchPaths.emplace_back(PATH_RESOURCE_TEST_DATA);
598     EXPECT_EQ(symbols->FindSymbolFile(symbolsFileSearchPaths, symboleFilePath).empty(), false);
599 
600     symbolsFileSearchPaths.clear();
601     EXPECT_EQ(symbols->FindSymbolFile(symbolsFileSearchPaths, symboleFilePath).empty(), true);
602 
603     symboleFilePath = PATH_RESOURCE_TEST_DATA + TEST_FILE_VMLINUX;
604     EXPECT_EQ(symbols->FindSymbolFile(symbolsFileSearchPaths, symboleFilePath).empty(), false);
605 
606     symbolsFileSearchPaths.emplace_back(PATH_RESOURCE_TEST_DATA);
607     EXPECT_EQ(symbols->FindSymbolFile(symbolsFileSearchPaths, symboleFilePath).empty(), false);
608 
609     symboleFilePath = TEST_FILE_ELF;
610     EXPECT_EQ(symbols->FindSymbolFile(symbolsFileSearchPaths, symboleFilePath).empty(), false);
611 
612     symbolsFileSearchPaths.clear();
613     EXPECT_EQ(symbols->FindSymbolFile(symbolsFileSearchPaths, symboleFilePath).empty(), true);
614 }
615 
616 /**
617  * @tc.name: GetBuildId
618  * @tc.desc:
619  * @tc.type: FUNC
620  */
621 HWTEST_F(SymbolsFileTest, GetBuildId, TestSize.Level2)
622 {
623     std::unique_ptr<SymbolsFile> symbolsFile = SymbolsFile::CreateSymbolsFile(SYMBOL_ELF_FILE);
624     // empty elf
625     EXPECT_EQ(symbolsFile->GetBuildId().empty(), true);
626     // set search path
627     ASSERT_EQ(symbolsFile->setSymbolsFilePath(PATH_RESOURCE_TEST_DATA), true);
628 
629     symbolsFile = SymbolsFile::CreateSymbolsFile(SYMBOL_ELF_FILE);
630     ASSERT_EQ(symbolsFile->setSymbolsFilePath(PATH_RESOURCE_TEST_DATA), true);
631     // kernel elf
632     EXPECT_EQ(symbolsFile->LoadSymbols(nullptr, TEST_FILE_VMLINUX), true);
633     EXPECT_EQ(symbolsFile->GetBuildId().empty(), false);
634 
635     symbolsFile = SymbolsFile::CreateSymbolsFile(SYMBOL_ELF_FILE);
636     ASSERT_EQ(symbolsFile->setSymbolsFilePath(PATH_RESOURCE_TEST_DATA), true);
637     // stripped elf
638     EXPECT_EQ(symbolsFile->LoadSymbols(nullptr, TEST_FILE_ELF), true);
639     EXPECT_EQ(symbolsFile->GetBuildId().empty(), false);
640 
641     symbolsFile = SymbolsFile::CreateSymbolsFile(SYMBOL_ELF_FILE);
642     ASSERT_EQ(symbolsFile->setSymbolsFilePath(PATH_RESOURCE_TEST_DATA), true);
643     // stripped elf
644     EXPECT_EQ(symbolsFile->LoadSymbols(nullptr, TEST_FILE_ELF_STRIPPED), true);
645     EXPECT_EQ(symbolsFile->GetBuildId().empty(), false);
646 }
647 
648 struct SectionInfo {
649     const std::string name;
650     uint64_t addr;
651     uint64_t size;
652     uint64_t offset;
653 };
654 
655 /**
656  * @tc.name: GetSectionInfo
657  * @tc.desc:
658  * @tc.type: FUNC
659  */
660 HWTEST_F(SymbolsFileTest, GetSectionInfo, TestSize.Level1)
661 {
662     std::unique_ptr<SymbolsFile> symbolsFile =
663         SymbolsFile::CreateSymbolsFile(SYMBOL_ELF_FILE, TEST_FILE_ELF_FULL_PATH);
664     ASSERT_EQ(symbolsFile->LoadDebugInfo(), true);
665     ASSERT_EQ(symbolsFile->LoadSymbols(), true);
666 
667     /*
668     from readelf -e elf32_test
669     32bit
670     [Nr] Name              Type            Addr     Off    Size   ES Flg Lk Inf Al
671     [ 0]                   NULL            00000000 000000 000000 00      0   0  0
672     [ 1] .interp           PROGBITS        000001b4 0001b4 000013 00   A  0   0  1
673     [ 2] .note.gnu.build-i NOTE            000001c8 0001c8 000024 00   A  0   0  4
674     [16] .text             PROGBITS        00001320 001320 000818 00  AX  0   0 16
675     [19] .eh_frame_hdr     PROGBITS        00002034 002034 0000dc 00   A  0   0  4
676     [20] .eh_frame         PROGBITS        00002110 002110 0003a0 00   A  0   0  4
677     [29] .symtab           SYMTAB          00000000 003034 000710 10     30  50  4
678     [30] .strtab           STRTAB          00000000 003744 000c3d 00      0   0  1
679     [31] .shstrtab         STRTAB          00000000 004381 00012a 00      0   0  1
680 
681     from readelf -e elf_test
682     64bit
683     Section Headers:
684     [Nr] Name              Type             Address           Offset
685         Size              EntSize          Flags  Link  Info  Align
686     [ 0]                   NULL             0000000000000000  00000000
687         0000000000000000  0000000000000000           0     0     0
688     [ 1] .interp           PROGBITS         0000000000000318  00000318
689         000000000000001c  0000000000000000   A       0     0     1
690     [ 2] .note.gnu.propert NOTE             0000000000000338  00000338
691         0000000000000020  0000000000000000   A       0     0     8
692     [16] .text             PROGBITS         00000000000022f0  000022f0
693         00000000000007b5  0000000000000000  AX       0     0     16
694     [19] .eh_frame_hdr     PROGBITS         0000000000003034  00003034
695         00000000000000bc  0000000000000000   A       0     0     4
696     [20] .eh_frame         PROGBITS         00000000000030f0  000030f0
697         0000000000000320  0000000000000000   A       0     0     8
698     [29] .symtab           SYMTAB           0000000000000000  00004040
699         00000000000009f0  0000000000000018          30    50     8
700     [30] .strtab           STRTAB           0000000000000000  00004a30
701         0000000000000bbb  0000000000000000           0     0     1
702     [31] .shstrtab         STRTAB           0000000000000000  000055eb
703         000000000000012c  0000000000000000           0     0     1
704     */
705 #ifdef __arm__
706     const std::vector<SectionInfo> sectionCheckList = {
707         {".note.gnu.build-id", 0x000001c8, 0x000024, 0x0001c8},
708         {".text", 0x00001320, 0x000818, 0x001320},
709         {".eh_frame_hdr", 0x00002034, 0x0000dc, 0x002034},
710         {".eh_frame", 0x00002110, 0x0003a0, 0x002110},
711         {".symtab", 0x00000000, 0x000710, 0x003034},
712         {".strtab", 0x00000000, 0x000c3d, 0x003744},
713     };
714 #else
715     const std::vector<SectionInfo> sectionCheckList = {
716         {".note.gnu.build-id", 0x0000000000000358, 0x0000000000000024, 0x00000358},
717         {".text", 0x00000000000022f0, 0x00000000000007b5, 0x000022f0},
718         {".eh_frame_hdr", 0x0000000000003034, 0x00000000000000bc, 0x00003034},
719         {".eh_frame", 0x00000000000030f0, 0x0000000000000320, 0x000030f0},
720         {".symtab", 0x00000000, 0x00000000000009f0, 0x00004040},
721         {".strtab", 0x00000000, 0x0000000000000bbb, 0x00004a30},
722     };
723 #endif
724     for (SectionInfo info : sectionCheckList) {
725         uint64_t addr;
726         uint64_t size;
727         uint64_t offset;
728         EXPECT_EQ(symbolsFile->GetSectionInfo(info.name, addr, size, offset), true);
729         EXPECT_EQ(addr, info.addr);
730         EXPECT_EQ(size, info.size);
731         EXPECT_EQ(offset, info.offset);
732         if (HasFailure()) {
733             printf("SectionInfo check failed at '%s', %" PRIx64 ",%" PRIx64 ",%" PRIx64 "\n",
734                    info.name.c_str(), info.addr, info.size, info.offset);
735         }
736     }
737 }
738 
739 #ifndef __arm__
740 /**
741  * @tc.name: GetHDRSectionInfo
742  * @tc.desc:
743  * @tc.type: FUNC
744  */
745 HWTEST_F(SymbolsFileTest, GetHDRSectionInfo, TestSize.Level1)
746 {
747     std::unique_ptr<SymbolsFile> symbolsFile =
748         SymbolsFile::CreateSymbolsFile(SYMBOL_ELF_FILE, TEST_FILE_ELF_FULL_PATH);
749 
750     ASSERT_EQ(symbolsFile->LoadSymbols(), true);
751     ASSERT_EQ(symbolsFile->LoadDebugInfo(), true);
752 
753     uint64_t ehFrameHdrElfOffset;
754     uint64_t fdeTableElfOffset;
755     uint64_t fdeTableSize;
756 
757     /*
758         readelf -e elf32_test | grep .eh_frame_hdr
759         [19] .eh_frame_hdr     PROGBITS        00002034 002034 0000dc 00   A  0   0  4
760 
761         readelf --debug-dump=frames elf32_test | grep FDE | wc -l
762         26
763 
764         readelf -e elf_test | grep .eh_frame_hdr
765         [19] .eh_frame_hdr     PROGBITS         0000000000003034  00003034
766 
767         readelf --debug-dump=frames elf_test | grep FDE | wc -l
768         22
769     */
770     symbolsFile->GetHDRSectionInfo(ehFrameHdrElfOffset, fdeTableElfOffset, fdeTableSize);
771 
772     EXPECT_EQ(ehFrameHdrElfOffset, 0x00003034u);
773     EXPECT_EQ(fdeTableSize, 22U);
774 }
775 
776 /**
777  * @tc.name: GetHDRSectionInfo
778  * @tc.desc:
779  * @tc.type: FUNC
780  */
781 HWTEST_F(SymbolsFileTest, GetHDRSectionInfoStripped, TestSize.Level2)
782 {
783     std::unique_ptr<SymbolsFile> symbolsFile = SymbolsFile::CreateSymbolsFile(
784         SYMBOL_ELF_FILE, PATH_RESOURCE_TEST_DATA + TEST_FILE_ELF_STRIPPED_NOEFHDR);
785 
786     ASSERT_EQ(symbolsFile->LoadDebugInfo(), true);
787 
788     uint64_t ehFrameHdrElfOffset;
789     uint64_t fdeTableElfOffset;
790     uint64_t fdeTableSize;
791 
792     symbolsFile->GetHDRSectionInfo(ehFrameHdrElfOffset, fdeTableElfOffset, fdeTableSize);
793     uint64_t addr = 0;
794     uint64_t size = 0;
795     uint64_t offset = 0;
796     EXPECT_EQ(symbolsFile->GetSectionInfo(EH_FRAME_HR, addr, size, offset), false);
797     EXPECT_EQ(offset, 0U);
798     EXPECT_EQ(size, 0U);
799     EXPECT_EQ(addr, 0U);
800 }
801 #endif
802 
803 /**
804  * @tc.name: CreateSymbolsFile
805  * @tc.desc:
806  * @tc.type: FUNC
807  */
808 HWTEST_F(SymbolsFileTest, CreateSymbolsFile, TestSize.Level1)
809 {
810     EXPECT_NE(SymbolsFile::CreateSymbolsFile(), nullptr);
811     EXPECT_NE(SymbolsFile::CreateSymbolsFile(SYMBOL_KERNEL_FILE), nullptr);
812     EXPECT_NE(SymbolsFile::CreateSymbolsFile(SYMBOL_KERNEL_MODULE_FILE), nullptr);
813     EXPECT_NE(SymbolsFile::CreateSymbolsFile(SYMBOL_KERNEL_THREAD_FILE), nullptr);
814     EXPECT_NE(SymbolsFile::CreateSymbolsFile(SYMBOL_ELF_FILE), nullptr);
815     EXPECT_NE(SymbolsFile::CreateSymbolsFile(SYMBOL_JAVA_FILE), nullptr);
816     EXPECT_NE(SymbolsFile::CreateSymbolsFile(SYMBOL_JS_FILE), nullptr);
817     EXPECT_NE(SymbolsFile::CreateSymbolsFile(SYMBOL_HAP_FILE), nullptr);
818     EXPECT_NE(SymbolsFile::CreateSymbolsFile(SYMBOL_CJ_FILE), nullptr);
819     EXPECT_NE(SymbolsFile::CreateSymbolsFile(SYMBOL_UNKNOW_FILE), nullptr);
820     EXPECT_NE(SymbolsFile::CreateSymbolsFile(SymbolsFileType(-1)), nullptr);
821     EXPECT_EQ(SymbolsFile::CreateSymbolsFile(SymbolsFileType(-2))->symbolFileType_,
822               SYMBOL_UNKNOW_FILE);
823 
824     EXPECT_EQ(SymbolsFile::CreateSymbolsFile(KERNEL_MMAP_NAME)->symbolFileType_,
825               SYMBOL_KERNEL_FILE);
826     EXPECT_EQ(SymbolsFile::CreateSymbolsFile(TEST_FILE_ELF_FULL_PATH)->symbolFileType_,
827               SYMBOL_ELF_FILE);
828 }
829 
830 /**
831  * @tc.name: LoadSymbolsFromSaved
832  * @tc.desc:
833  * @tc.type: FUNC
834  */
835 HWTEST_F(SymbolsFileTest, LoadSymbolsFromSaved, TestSize.Level1)
836 {
837     SymbolFileStruct sfs;
838     for (unsigned int type = 0; type < SYMBOL_UNKNOW_FILE; type++) {
839         sfs.filePath_ = std::to_string(rnd_());
840         sfs.symbolType_ = type;
841         sfs.textExecVaddrFileOffset_ = rnd_();
842         sfs.textExecVaddr_ = rnd_();
843         sfs.buildId_ = std::to_string(rnd_());
844         int nameIndex = 0;
845         // after LoadSymbolsFromSaved it will sort from low to high
846         // so we make a order item to test
847         constexpr int rndMax = 10000;
848         std::uniform_int_distribution<int> rndLimi(0, rndMax);
849         sfs.symbolStructs_.emplace_back(rndLimi(rnd_) + nameIndex * rndMax, rnd_(),
850                                         std::to_string(nameIndex));
851         nameIndex++;
852         sfs.symbolStructs_.emplace_back(rndLimi(rnd_) + nameIndex * rndMax, rnd_(),
853                                         std::to_string(nameIndex));
854         nameIndex++;
855         sfs.symbolStructs_.emplace_back(rndLimi(rnd_) + nameIndex * rndMax, rnd_(),
856                                         std::to_string(nameIndex));
857         nameIndex++;
858 
859         // setup the min vaddr
860 
861         std::unique_ptr<SymbolsFile> symbolsFile = SymbolsFile::LoadSymbolsFromSaved(sfs);
862 
863         EXPECT_EQ(symbolsFile->filePath_, sfs.filePath_);
864         EXPECT_EQ(symbolsFile->symbolFileType_, sfs.symbolType_);
865         EXPECT_EQ(symbolsFile->textExecVaddr_, sfs.textExecVaddr_);
866         EXPECT_EQ(symbolsFile->textExecVaddrFileOffset_, sfs.textExecVaddrFileOffset_);
867         EXPECT_EQ(symbolsFile->GetBuildId(), sfs.buildId_);
868         EXPECT_EQ(symbolsFile->GetSymbols().size(), sfs.symbolStructs_.size());
869 
870         for (DfxSymbol symbol : symbolsFile->GetSymbols()) {
871             SymbolStruct symbolStruct = sfs.symbolStructs_.front();
872             EXPECT_EQ(symbol.funcVaddr_, symbolStruct.vaddr_);
873             EXPECT_EQ(symbol.size_, symbolStruct.len_);
874             EXPECT_EQ(symbol.name_, symbolStruct.symbolName_);
875             sfs.symbolStructs_.erase(sfs.symbolStructs_.begin());
876         }
877     }
878 }
879 
880 /**
881  * @tc.name: exportSymbolToFileFormatMatched
882  * @tc.desc:
883  * @tc.type: FUNC
884  */
885 HWTEST_F(SymbolsFileTest, exportSymbolToFileFormatMatched, TestSize.Level2)
886 {
887     for (int type = 0; type < SYMBOL_UNKNOW_FILE; type++) {
888         auto symbolsFile = SymbolsFile::CreateSymbolsFile();
889         symbolsFile->filePath_ = std::to_string(rnd_());
890         symbolsFile->symbolFileType_ = static_cast<SymbolsFileType>(type);
891         symbolsFile->textExecVaddrFileOffset_ = rnd_();
892         symbolsFile->buildId_ = std::to_string(rnd_());
893         int nameIndex = 0;
894         // after LoadSymbolsFromSaved it will sort from low to high
895         // so we make a order item to test
896         constexpr int rndMax = 10000;
897         std::uniform_int_distribution<int> rndLimi(0, rndMax);
898         symbolsFile->symbols_.emplace_back(rndLimi(rnd_) + nameIndex * rndMax, rnd_(),
899                                            std::to_string(nameIndex), symbolsFile->filePath_);
900         nameIndex++;
901         symbolsFile->symbols_.emplace_back(rndLimi(rnd_) + nameIndex * rndMax, rnd_(),
902                                            std::to_string(nameIndex), symbolsFile->filePath_);
903         nameIndex++;
904         symbolsFile->symbols_.emplace_back(rndLimi(rnd_) + nameIndex * rndMax, rnd_(),
905                                            std::to_string(nameIndex), symbolsFile->filePath_);
906         nameIndex++;
907 
908         // setup the min vaddr
909         symbolsFile->textExecVaddr_ = std::numeric_limits<uint64_t>::max();
910 
911         for (auto &symbol : symbolsFile->symbols_) {
912             symbolsFile->textExecVaddr_ = std::min(symbol.funcVaddr_, symbolsFile->textExecVaddr_);
913         }
914 
915         // access last one to make it as matched.
916         uint64_t matchedVaddr = symbolsFile->symbols_.back().funcVaddr_;
917         auto symbol = symbolsFile->GetSymbolWithVaddr(matchedVaddr);
918         EXPECT_EQ(symbol.funcVaddr_, matchedVaddr);
919         if (HasFailure()) {
920             PrintSymbols(symbolsFile->GetSymbols());
921         }
922 
923         SymbolFileStruct sfs {};
924         symbolsFile->ExportSymbolToFileFormat(sfs);
925 
926         EXPECT_EQ(symbolsFile->symbolFileType_, sfs.symbolType_);
927         EXPECT_EQ(symbolsFile->textExecVaddrFileOffset_, sfs.textExecVaddrFileOffset_);
928         EXPECT_EQ(symbolsFile->GetBuildId(), sfs.buildId_);
929 
930         // matched one should be remove
931         EXPECT_EQ(sfs.symbolStructs_.size(), 1u);
932         for (SymbolStruct symbolStruct : sfs.symbolStructs_) {
933             // nomore found for matched vaddr
934             EXPECT_EQ(symbolStruct.vaddr_, matchedVaddr);
935         }
936     }
937 }
938 
939 /**
940  * @tc.name: UpdateBuildIdIfMatch
941  * @tc.desc:
942  * @tc.type: FUNC
943  */
944 HWTEST_F(SymbolsFileTest, UpdateBuildIdIfMatch, TestSize.Level1)
945 {
946     auto file = SymbolsFile::CreateSymbolsFile();
947     file->buildId_ = "123";
948     file->UpdateBuildIdIfMatch("456");
949     EXPECT_STREQ(file->buildId_.c_str(), "123");
950     EXPECT_STRNE(file->buildId_.c_str(), "456");
951 }
952 
953 /**
954  * @tc.name: CreateCJSymbolsFile
955  * @tc.desc:
956  * @tc.type: FUNC
957  */
958 HWTEST_F(SymbolsFileTest, CreateCJSymbolsFile, TestSize.Level1)
959 {
960     std::string cjLibPath = "/system/lib64/platformsdk/cjsdk/libcangjie-std-core.so";
961     std::filesystem::path cjPath(cjLibPath);
962     if (std::filesystem::exists(cjPath)) {
963         auto file = SymbolsFile::CreateSymbolsFile(cjLibPath);
964         EXPECT_NE(file, nullptr);
965         EXPECT_EQ(file->symbolFileType_, SYMBOL_CJ_FILE);
966     }
967 }
968 
969 /**
970  * @tc.name: CreateCJSymbolsFile2
971  * @tc.desc:
972  * @tc.type: FUNC
973  */
974 HWTEST_F(SymbolsFileTest, CreateCJSymbolsFile2, TestSize.Level1)
975 {
976     std::string cjLibPath = "/data/storage/libohos_app_cangjie_entry.so";
977     std::filesystem::path cjPath(cjLibPath);
978     auto file = SymbolsFile::CreateSymbolsFile(cjLibPath);
979     EXPECT_NE(file, nullptr);
980 }
981 
982 /**
983  * @tc.name: CreateV8Symbols
984  * @tc.desc: Test CreateSymbolsFile function and parse symbol
985  * @tc.type: FUNC
986  */
987 HWTEST_F(SymbolsFileTest, CreateV8Symbols, TestSize.Level1)
988 {
989     SymbolsFile::needParseJsFunc_ = false;
990     const std::string filename = "[anon:JSVM_JIT]";
991     auto symbolsFile = SymbolsFile::CreateSymbolsFile(filename);
992     EXPECT_EQ(symbolsFile->IsV8(), true);
993     uint64_t ip = rnd_();
994     uint64_t begin = rnd_();
995     uint64_t len = rnd_();
996     uint64_t offset = rnd_();
997     uint32_t prot = rnd_();
998     std::shared_ptr<DfxMap> map = std::make_shared<DfxMap>(begin, begin + len, offset, prot, filename);
999     EXPECT_EQ(symbolsFile->LoadDebugInfo(map, "/system/lib64/libv8_shared.so"), true);
1000     EXPECT_EQ(symbolsFile->LoadSymbols(map, "/system/lib64/libv8_shared.so"), true);
1001     auto symbol = symbolsFile->GetSymbolWithPcAndMap(ip, map);
1002     EXPECT_EQ(symbol.IsValid(), false);
1003 }
1004 
1005 /**
1006  * @tc.name: CreateV8Symbols2
1007  * @tc.desc: Test CreateSymbolsFile function and parse symbol
1008  * @tc.type: FUNC
1009  */
1010 HWTEST_F(SymbolsFileTest, CreateV8Symbols2, TestSize.Level1)
1011 {
1012     SymbolsFile::needParseJsFunc_ = false;
1013     const std::string filename = "[anon:JSVM_JIT]";
1014     auto symbolsFile = SymbolsFile::CreateSymbolsFile(filename);
1015     EXPECT_EQ(symbolsFile->IsV8(), true);
1016     uint64_t ip = rnd_();
1017     uint64_t begin = rnd_();
1018     uint64_t len = rnd_();
1019     uint64_t offset = rnd_();
1020     uint32_t prot = rnd_();
1021     std::shared_ptr<DfxMap> map = std::make_shared<DfxMap>(begin, begin + len, offset, prot, filename);
1022     symbolsFile->symbolsMap_.insert(std::make_pair(ip,
1023         DfxSymbol(ip, 0, "", "", map->name)));
1024     auto symbol = symbolsFile->GetSymbolWithPcAndMap(ip, map);
1025     EXPECT_EQ(symbol.IsValid(), true);
1026 }
1027 
1028 /**
1029  * @tc.name: CreateV8Symbols3
1030  * @tc.desc: Only test CreateSymbolsFile function
1031  * @tc.type: FUNC
1032  */
1033 HWTEST_F(SymbolsFileTest, CreateV8Symbols3, TestSize.Level1)
1034 {
1035     SymbolsFile::needParseJsFunc_ = true;
1036     const std::string filename = "[anon:ARKWEB_JIT]";
1037     auto symbolsFile = SymbolsFile::CreateSymbolsFile(filename);
1038     EXPECT_EQ(symbolsFile->IsV8(), false);
1039     uint64_t ip = rnd_();
1040     uint64_t begin = rnd_();
1041     uint64_t len = rnd_();
1042     uint64_t offset = rnd_();
1043     uint32_t prot = rnd_();
1044     std::shared_ptr<DfxMap> map = std::make_shared<DfxMap>(begin, begin + len, offset, prot, filename);
1045     symbolsFile->symbolsMap_.insert(std::make_pair(ip,
1046         DfxSymbol(ip, 0, "", "", map->name)));
1047     auto symbol = symbolsFile->GetSymbolWithPcAndMap(ip, map);
1048     EXPECT_EQ(symbol.IsValid(), true);
1049 }
1050 
1051 /**
1052  * @tc.name: CreateV8Symbols4
1053  * @tc.desc: Test CreateSymbolsFile function and parse symbol
1054  * @tc.type: FUNC
1055  */
1056 HWTEST_F(SymbolsFileTest, CreateV8Symbols4, TestSize.Level1)
1057 {
1058     SymbolsFile::needParseJsFunc_ = false;
1059     const std::string filename = "[anon:JSVM_JIT]";
1060     auto symbolsFile = SymbolsFile::CreateSymbolsFile(filename);
1061     EXPECT_EQ(symbolsFile->IsV8(), true);
1062     uint64_t ip = rnd_();
1063     uint64_t begin = rnd_();
1064     uint64_t len = rnd_();
1065     uint64_t offset = rnd_();
1066     uint32_t prot = rnd_();
1067     std::shared_ptr<DfxMap> map = std::make_shared<DfxMap>(begin, begin + len, offset, prot, filename);
1068     EXPECT_EQ(symbolsFile->LoadDebugInfo(map, "/system/lib64/libv8_shared.so"), true);
1069     EXPECT_EQ(symbolsFile->LoadSymbols(map, "/system/lib64/libv8_shared.so"), true);
1070     auto symbol = symbolsFile->GetSymbolWithPcAndMap(ip, map);
1071     EXPECT_EQ(symbol.IsValid(), false);
1072 }
1073 
1074 /**
1075  * @tc.name: V8SymbolsErr
1076  * @tc.desc: Test CreateSymbolsFile error
1077  * @tc.type: FUNC
1078  */
1079 HWTEST_F(SymbolsFileTest, V8SymbolsErr, TestSize.Level1)
1080 {
1081     const std::string filename = "[anon:JSVM_JIT]";
1082     auto symbolsFile = SymbolsFile::CreateSymbolsFile(filename);
1083     std::shared_ptr<DfxMap> map = nullptr;
1084     uint64_t ip = rnd_();
1085     EXPECT_EQ(symbolsFile->LoadDebugInfo(map, "/system/lib64/libv8_shared.so"), false);
1086     EXPECT_EQ(symbolsFile->LoadSymbols(map, "/system/lib64/libv8_shared.so"), false);
1087     auto symbol = symbolsFile->GetSymbolWithPcAndMap(ip, map);
1088     EXPECT_EQ(symbol.IsValid(), false);
1089 }
1090 } // namespace HiPerf
1091 } // namespace Developtools
1092 } // namespace OHOS
1093