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