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