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 <iostream>
17 #include <string>
18
19 #include <cstdio>
20
21 #include "elf_parser.h"
22 #include "elf_parser_test.h"
23
24 using namespace testing::ext;
25 using namespace std;
26 using namespace OHOS::HiviewDFX;
27 using namespace OHOS::Developtools::HiPerf::ELF;
28 namespace OHOS {
29 namespace Developtools {
30 namespace HiPerf {
31 namespace UnitTest {
32 namespace {
33 const std::string file32 {"resource/testdata/elf32_test"};
34 const std::string file64 {"resource/testdata/elf_test"};
35 const std::string ehdr32 {"resource/testdata/ehdr_from_readelf_32"};
36 const std::string ehdr64 {"resource/testdata/ehdr_from_readelf_64"};
37 const std::string shdrs32 {"resource/testdata/shdrs_from_readelf_32"};
38 const std::string shdrs64 {"resource/testdata/shdrs_from_readelf_64"};
39 const std::string phdrs32 {"resource/testdata/phdrs_from_readelf_32"};
40 const std::string phdrs64 {"resource/testdata/phdrs_from_readelf_64"};
41 const std::string syms32 {"resource/testdata/syms_from_readelf_32"};
42 const std::string syms64 {"resource/testdata/syms_from_readelf_64"};
43 } // namespace
44
GetNextLine(FILE * fp,int * status)45 static const std::string GetNextLine(FILE *fp, int *status)
46 {
47 constexpr int bufSize {128};
48 char buf[bufSize];
49 if (memset_s(buf, sizeof(buf), '\0', sizeof(buf)) != EOK) {
50 HLOGV("memset_s() failed");
51 return "";
52 }
53 if (fgets(buf, bufSize, fp) == nullptr) {
54 HLOGV("fgets() failed");
55 *status = -1;
56 return "";
57 }
58 *status = 0;
59 std::string res {buf};
60 if (res.back() == '\n') {
61 res = res.substr(0, res.length() - 1);
62 }
63 return res;
64 }
65
MemCmp(void * p1,void * p2,std::size_t num)66 static int MemCmp(void *p1, void *p2, std::size_t num)
67 {
68 char *cstrp1 = static_cast<char *>(p1);
69 char *cstrp2 = static_cast<char *>(p2);
70 if (num == 0) {
71 return 0;
72 }
73 for (std::size_t count = 0; count < num; ++count) {
74 if (cstrp1[count] != cstrp2[count]) {
75 return count;
76 }
77 }
78 return num;
79 }
80
ElfFileFromReadelf(ElfFileType fileType)81 ElfFileFromReadelf::ElfFileFromReadelf(ElfFileType fileType)
82 {
83 if (fileType == ElfFileType::ELF32) {
84 ehdrFP_ = fopen(ehdr32.c_str(), "rb");
85 if (ehdrFP_ == nullptr) {
86 HLOGV("fopen(ehdr32, \"r\") failed");
87 }
88 shdrsFP_ = fopen(shdrs32.c_str(), "rb");
89 if (shdrsFP_ == nullptr) {
90 HLOGV("fopen(shdrs32, \"r\") failed");
91 }
92 phdrsFP_ = fopen(phdrs32.c_str(), "rb");
93 if (phdrsFP_ == nullptr) {
94 HLOGV("fopen(phdrs32, \"r\") failed");
95 }
96 symTabFP_ = fopen(syms32.c_str(), "rb");
97 if (symTabFP_ == nullptr) {
98 HLOGV("fopen(syms32, \"r\") failed");
99 }
100 }
101 if (fileType == ElfFileType::ELF64) {
102 ehdrFP_ = fopen(ehdr64.c_str(), "rb");
103 if (ehdrFP_ == nullptr) {
104 HLOGV("fopen(ehdr64, \"r\") failed");
105 }
106 shdrsFP_ = fopen(shdrs64.c_str(), "rb");
107 if (shdrsFP_ == nullptr) {
108 HLOGV("fopen(shdrs64, \"r\") failed");
109 }
110 phdrsFP_ = fopen(phdrs64.c_str(), "rb");
111 if (phdrsFP_ == nullptr) {
112 HLOGV("fopen(phdrs64, \"r\") failed");
113 }
114 symTabFP_ = fopen(syms64.c_str(), "rb");
115 if (symTabFP_ == nullptr) {
116 HLOGV("fopen(syms64, \"r\") failed");
117 }
118 }
119 }
120
~ElfFileFromReadelf()121 ElfFileFromReadelf::~ElfFileFromReadelf()
122 {
123 if (ehdrFP_ != nullptr) {
124 fclose(ehdrFP_);
125 ehdrFP_ = nullptr;
126 }
127 if (shdrsFP_ != nullptr) {
128 fclose(shdrsFP_);
129 shdrsFP_ = nullptr;
130 }
131 if (phdrsFP_ != nullptr) {
132 fclose(phdrsFP_);
133 phdrsFP_ = nullptr;
134 }
135 if (symTabFP_ != nullptr) {
136 fclose(symTabFP_);
137 symTabFP_ = nullptr;
138 }
139 }
140
MakeUnique(ElfFileType fileType)141 std::unique_ptr<ElfFileFromReadelf> ElfFileFromReadelf::MakeUnique(ElfFileType fileType)
142 {
143 std::unique_ptr<ElfFileFromReadelf> elfFile {new (std::nothrow) ElfFileFromReadelf(fileType)};
144 if (elfFile == nullptr) {
145 HLOGV("ElfFileFromReadelf(fileType) failed:");
146 return nullptr;
147 }
148 if (!elfFile->Init()) {
149 HLOGV("ElfFileFromReadelf::Init() failed");
150 return nullptr;
151 }
152 HLOGD("ElfFileFromReadelf::MakeUnique() done");
153 return elfFile;
154 }
155
Init()156 bool ElfFileFromReadelf::Init()
157 {
158 if (!IsOpened()) {
159 HLOGV("IsOpened() returns false");
160 return false;
161 }
162 HLOGD("all commands done");
163 if (!ParseElfHeader()) {
164 HLOGV("ElfFileFromReadelf::ParseElfHeader() failed");
165 return false;
166 }
167 HLOGD("ParseElfHeader() done");
168 if (ehdr_->ehdrIdent_[EI_CLASS] == ELFCLASS32) {
169 if (!ParsePrgHeaders32()) {
170 HLOGV("ElfFileFromReadelf::ParsePrgHeader() failed");
171 return false;
172 }
173 HLOGD("ParsePrgHeaders32() done");
174 if (!ParseSecHeaders32()) {
175 HLOGV("ElfFileFromReadelf::ParseSecHeader() failed");
176 return false;
177 }
178 HLOGD("ParseSecHeaders32() done");
179 } else if (ehdr_->ehdrIdent_[EI_CLASS] == ELFCLASS64) {
180 if (!ParsePrgHeaders64()) {
181 HLOGV("ElfFileFromReadelf::ParsePrgHeader() failed");
182 return false;
183 }
184 HLOGD("ParsePrgHeaders64() done");
185 if (!ParseSecHeaders64()) {
186 HLOGV("ElfFileFromReadelf::ParseSecHeader() failed");
187 return false;
188 }
189 HLOGD("ParseSecHeaders64() done");
190 } else {
191 HLOGV("not an elf file");
192 return false;
193 }
194 if (!ParseSymTable()) {
195 HLOGV("ElfFileFromReadelf::ParseSymTable() failed");
196 return false;
197 }
198 HLOGD("ParseSymTable() done");
199 HLOGD("ElfFileFromReadelf::Init() done");
200 return true;
201 }
202
IsOpened()203 bool ElfFileFromReadelf::IsOpened()
204 {
205 if (ehdrFP_ == nullptr) {
206 HLOGV("ehdrFP_ = nullptr");
207 return false;
208 }
209 if (shdrsFP_ == nullptr) {
210 HLOGV("shdrsFP_ = nullptr");
211 return false;
212 }
213 if (phdrsFP_ == nullptr) {
214 HLOGV("phdrsFP_ = nullptr");
215 return false;
216 }
217 if (symTabFP_ == nullptr) {
218 HLOGV("symTabFP_ = nullptr");
219 return false;
220 }
221 return true;
222 }
223
ParseElfHeader()224 bool ElfFileFromReadelf::ParseElfHeader()
225 {
226 ehdr_ = EhdrFromReadelf::MakeUnique(ehdrFP_);
227 if (ehdr_ == nullptr) {
228 HLOGV("EhdrFromReadelf::MakeUnique(ehdrFP_) failed");
229 return false;
230 }
231 return true;
232 }
233
ParsePrgHeaders64()234 bool ElfFileFromReadelf::ParsePrgHeaders64()
235 {
236 std::string line1 {};
237 std::string line2 {};
238 while (true) {
239 line1 = GetNextPhdrLine();
240 line2 = GetNextPhdrLine();
241 if (line1 == "" or line2 == "") {
242 HLOGV("no more program header lines");
243 break;
244 }
245 auto phdr = PhdrFromReadelf::MakeUnique(line1 + line2);
246 if (phdr == nullptr) {
247 HLOGV("64 bit PhdrFromReadelf::MakeUnique(line) failed:");
248 HLOGV(" line1 = %s", line1.c_str());
249 HLOGV(" line2 = %s", line2.c_str());
250 return false;
251 }
252 phdrs_.push_back(std::move(phdr));
253 }
254 return true;
255 }
256
ParsePrgHeaders32()257 bool ElfFileFromReadelf::ParsePrgHeaders32()
258 {
259 std::string line {};
260 while (true) {
261 line = GetNextPhdrLine();
262 if (line == "") {
263 HLOGV("no more program header lines");
264 break;
265 }
266 auto phdr = PhdrFromReadelf::MakeUnique(line);
267 if (phdr == nullptr) {
268 HLOGV("32 bit PhdrFromReadelf::MakeUnique(line) failed:");
269 HLOGV(" line = %s", line.c_str());
270 return false;
271 }
272 phdrs_.push_back(std::move(phdr));
273 }
274 return true;
275 }
276
ParseSecHeaders64()277 bool ElfFileFromReadelf::ParseSecHeaders64()
278 {
279 std::string line1 {};
280 std::string line2 {};
281 while (true) {
282 int status {0};
283 line1 = GetNextShdrLine();
284 line2 = GetNextLine(shdrsFP_, &status);
285 if (line1 == "" or line2 == "") {
286 HLOGV("no more section header lines");
287 break;
288 }
289 auto shdr = ShdrFromReadelf::MakeUnique(line1 + line2);
290 if (shdr == nullptr) {
291 HLOGV("ShdrFromReadelf::MakeUnique(line1, line2) returns nullptr:");
292 HLOGV(" line1 = %s line2 = %s", line1.c_str(), line2.c_str());
293 return false;
294 }
295 shdrs_.push_back(std::move(shdr));
296 }
297 return true;
298 }
299
ParseSecHeaders32()300 bool ElfFileFromReadelf::ParseSecHeaders32()
301 {
302 std::string line {};
303 while (true) {
304 int status {0};
305 line = GetNextShdrLine();
306 if (line == "") {
307 HLOGV("no more section header lines");
308 break;
309 }
310 auto shdr = ShdrFromReadelf::MakeUnique(line);
311 if (shdr == nullptr) {
312 HLOGV("ShdrFromReadelf::MakeUnique(line) returns nullptr:");
313 HLOGV(" line = %s", line.c_str());
314 return false;
315 }
316 shdrs_.push_back(std::move(shdr));
317 }
318 return true;
319 }
320
ParseSymTable()321 bool ElfFileFromReadelf::ParseSymTable()
322 {
323 std::string line {};
324 while (true) {
325 line = GetNextSymLine();
326 if (line == "") {
327 HLOGV("no more symbol lines");
328 break;
329 }
330 if (line.find(".dynsym") != std::string::npos) {
331 if (!ParseSymsInDynSym()) {
332 HLOGV("ParseSymsInDynSym() returns false");
333 return false;
334 }
335 }
336 if (!ParseSymsInSymTab()) {
337 HLOGV("ParseSymsInSymTab() returns false");
338 return false;
339 }
340 }
341 HLOGD("ElfFileFromReadelf::ParseSymTable() done");
342 return true;
343 }
344
ParseSymsInDynSym()345 bool ElfFileFromReadelf::ParseSymsInDynSym()
346 {
347 std::string line {};
348 while (true) {
349 line = GetNextSymLine();
350 if (line == "") {
351 HLOGV("no more symbol lines");
352 break;
353 }
354 if (line.find(".symtab") != std::string::npos) {
355 HLOGV("no more dynsym lines");
356 break;
357 }
358 auto dynSym = ElfSymbolFromReadelf::MakeUnique(line);
359 if (dynSym == nullptr) {
360 HLOGV("ElfSymbolFromReadelf::MakeUnique(line) failed:");
361 HLOGV(" line = %s", line.c_str());
362 return false;
363 }
364 if (dynSym->num_ != 0) {
365 dynSyms_.push_back(std::move(dynSym));
366 }
367 }
368 return true;
369 }
370
ParseSymsInSymTab()371 bool ElfFileFromReadelf::ParseSymsInSymTab()
372 {
373 std::string line {};
374 while (true) {
375 line = GetNextSymLine();
376 if (line == "") {
377 HLOGV("no more symtab lines");
378 break;
379 }
380 auto sym = ElfSymbolFromReadelf::MakeUnique(line);
381 if (sym == nullptr) {
382 HLOGV("ElfSymbolFromReadelf::MakeUnique(line) failed:");
383 HLOGV(" line = %s", line.c_str());
384 return false;
385 }
386 if (sym->num_ != 0) {
387 syms_.push_back(std::move(sym));
388 }
389 }
390 return true;
391 }
392
GetNextPhdrLine()393 const std::string ElfFileFromReadelf::GetNextPhdrLine()
394 {
395 const std::string effectFlag {"0x00"};
396 std::string line {};
397 int status {0};
398 while (true) {
399 line = GetNextLine(phdrsFP_, &status);
400 if (status == -1) {
401 HLOGV("GetNextLine(phdrsFP_, &status) error:");
402 line = "";
403 break;
404 }
405 if (line.find(effectFlag) != std::string::npos) {
406 HLOGV("effective program header line: %s", line.c_str());
407 break;
408 }
409 }
410 return line;
411 }
412
GetNextShdrLine()413 const std::string ElfFileFromReadelf::GetNextShdrLine()
414 {
415 const std::string effectFlag {"]"};
416 std::string line {};
417 int status {0};
418 while (true) {
419 line = GetNextLine(shdrsFP_, &status);
420 if (status == -1) {
421 HLOGV("GetNextLine(phdrsFP_, &status) error:");
422 line = "";
423 break;
424 }
425 auto pos = line.find(effectFlag);
426 if ((pos != std::string::npos) and isdigit(line.at(pos - 1))) {
427 HLOGV("effective section header line: %s", line.c_str());
428 break;
429 }
430 }
431 return line;
432 }
433
GetNextSymLine()434 const std::string ElfFileFromReadelf::GetNextSymLine()
435 {
436 const std::string effectFlag {":"};
437 std::string line {};
438 int status {0};
439 while (true) {
440 line = GetNextLine(symTabFP_, &status);
441 if (status == -1) {
442 HLOGV("GetNextLine(phdrsFP_, &status) error:");
443 line = "";
444 break;
445 }
446 if (line.find(".dynsym") != std::string::npos) {
447 break;
448 }
449 if (line.find(".symtab") != std::string::npos) {
450 break;
451 }
452 auto pos = line.find(effectFlag);
453 if ((pos != std::string::npos) and isdigit(line.at(pos - 1))) {
454 HLOGV("effective symbol line: %s", line.c_str());
455 break;
456 }
457 }
458 return line;
459 }
460
MakeUnique(const std::string & line)461 std::unique_ptr<ElfSymbolFromReadelf> ElfSymbolFromReadelf::MakeUnique(const std::string &line)
462 {
463 std::unique_ptr<ElfSymbolFromReadelf> elfSym {new (std::nothrow) ElfSymbolFromReadelf()};
464 if (elfSym == nullptr) {
465 HLOGV("ElfSymbolFromReadelf() failed");
466 return nullptr;
467 }
468 if (!elfSym->Init(line)) {
469 HLOGV("ElfSymbolFromReadelf::Init(line) failed:");
470 HLOGV(" line = %s", line.c_str());
471 return nullptr;
472 }
473 HLOGD("ElfSymbolFromReadelf::MakeUnique() done");
474 return elfSym;
475 }
476
Init(const std::string & line)477 bool ElfSymbolFromReadelf::Init(const std::string &line)
478 {
479 auto num = GetNum(line);
480 if (num == -1) {
481 HLOGV("ElfSymbolFromReadelf::GetNum(line) failed:");
482 HLOGV(" line = %s", line.c_str());
483 return false;
484 }
485 num_ = static_cast<uint32_t>(num);
486 auto value = GetValue(line);
487 if (value == -1) {
488 HLOGV("ElfSymbolFromReadelf::GetValue(line) failed");
489 HLOGV(" line = %s", line.c_str());
490 return false;
491 }
492 value_ = static_cast<uint64_t>(value);
493 auto size = GetSize(line);
494 if (size == -1) {
495 HLOGV("ElfSymbolFromReadelf::GetSize(line) failed");
496 HLOGV(" line = %s", line.c_str());
497 return false;
498 }
499 size_ = static_cast<uint64_t>(size);
500 name_ = GetName(line);
501 return true;
502 }
503
GetNum(const std::string & line)504 int64_t ElfSymbolFromReadelf::GetNum(const std::string &line)
505 {
506 int64_t res {-1};
507 auto strVec = StringSplit(line, " ");
508 constexpr int numIndex {0};
509 if (strVec.size() <= numIndex) {
510 return res;
511 }
512 std::string numStr = strVec[numIndex];
513 numStr = numStr.substr(0, numStr.size() - 1);
514 if (IsDigits(numStr)) {
515 res = std::stoll(numStr);
516 }
517 return res;
518 }
519
GetValue(const std::string & line)520 int64_t ElfSymbolFromReadelf::GetValue(const std::string &line)
521 {
522 int64_t res {-1};
523 auto strVec = StringSplit(line, " ");
524 constexpr int valIndex {1};
525 if (strVec.size() <= valIndex) {
526 return res;
527 }
528 std::string valStr = strVec[valIndex];
529 if (IsHexDigits(valStr)) {
530 constexpr int base {16};
531 res = std::stoll(valStr, nullptr, base);
532 }
533 return res;
534 }
535
GetSize(const std::string & line)536 int64_t ElfSymbolFromReadelf::GetSize(const std::string &line)
537 {
538 int64_t res {-1};
539 auto strVec = StringSplit(line, " ");
540 constexpr int sizeIndex {2};
541 if (strVec.size() <= sizeIndex) {
542 return res;
543 }
544 std::string sizeStr = strVec[sizeIndex];
545 if (IsDigits(sizeStr)) {
546 res = std::stoll(sizeStr);
547 }
548 return res;
549 }
550
GetName(const std::string & line)551 const std::string ElfSymbolFromReadelf::GetName(const std::string &line)
552 {
553 std::string res {};
554 auto strVec = StringSplit(line, " ");
555 constexpr int nameIndex {7};
556 if (strVec.size() > nameIndex) {
557 res = strVec.back();
558 }
559 return res;
560 }
561
MakeUnique(const std::string & line)562 std::unique_ptr<ShdrFromReadelf> ShdrFromReadelf::MakeUnique(const std::string &line)
563 {
564 std::unique_ptr<ShdrFromReadelf> shdr {new (std::nothrow) ShdrFromReadelf()};
565 if (shdr == nullptr) {
566 HLOGV("ShdrFromReadelf() failed");
567 return nullptr;
568 }
569 if (!shdr->Init(line)) {
570 HLOGV("ShdrFromReadelf::Init(line) failed:");
571 HLOGV(" line = %s", line.c_str());
572 return nullptr;
573 }
574 HLOGD("ShdrFromReadelf::MakeUnique() done");
575 return shdr;
576 }
577
Init(const std::string & line)578 bool ShdrFromReadelf::Init(const std::string &line)
579 {
580 auto secIndex = GetSecIndex(line);
581 if (secIndex == -1) {
582 HLOGV("ShdrFromReadelf::GetSecIndex(line) failed");
583 HLOGV(" line = %s", line.c_str());
584 return false;
585 }
586 secIndex_ = static_cast<uint32_t>(secIndex);
587 secName_ = GetName(line);
588 auto secVaddr = GetAddress(line);
589 if (secVaddr == -1) {
590 HLOGV("ShdrFromReadelf::GetAddress(line) failed");
591 HLOGV(" line = %s", line.c_str());
592 return false;
593 }
594 secVaddr_ = static_cast<uint32_t>(secVaddr);
595 auto fileOffset = GetFileOffset(line);
596 if (fileOffset == -1) {
597 HLOGV("ShdrFromReadelf::GetFileOffset(line) failed");
598 HLOGV(" line = %s", line.c_str());
599 return false;
600 }
601 fileOffset_ = static_cast<uint64_t>(fileOffset);
602 auto secSize = GetSecSize(line);
603 if (secSize == -1) {
604 HLOGV("ShdrFromReadelf::GetSecSize(line) failed");
605 HLOGV(" line = %s", line.c_str());
606 return false;
607 }
608 secSize_ = static_cast<uint64_t>(secSize);
609 auto secEntrySize = GetEntrySize(line);
610 if (secEntrySize == -1) {
611 HLOGV("ShdrFromReadelf::GetEntrySize(line) failed");
612 HLOGV(" line = %s", line.c_str());
613 return false;
614 }
615 secEntrySize_ = static_cast<uint64_t>(secEntrySize);
616 auto link = GetLink(line);
617 if (link == -1) {
618 HLOGV("ShdrFromReadelf::GetLink(line) failed");
619 HLOGV(" line = %s", line.c_str());
620 return false;
621 }
622 link_ = static_cast<uint32_t>(link);
623 auto info = GetInfo(line);
624 if (info == -1) {
625 HLOGV("ShdrFromReadelf::GetLink(line) failed");
626 HLOGV(" line = %s", line.c_str());
627 return false;
628 }
629 info_ = static_cast<uint32_t>(info);
630 auto secAddrAlign = GetAlign(line);
631 if (secAddrAlign == -1) {
632 HLOGV("ShdrFromReadelf::GetAlign(line) failed");
633 HLOGV(" line = %s", line.c_str());
634 return false;
635 }
636 secAddrAlign_ = static_cast<uint64_t>(secAddrAlign);
637 return true;
638 }
639
GetSecIndex(const std::string & line)640 int64_t ShdrFromReadelf::GetSecIndex(const std::string &line)
641 {
642 int64_t res {-1};
643 auto pos = line.find("[");
644 if (pos == std::string::npos) {
645 HLOGV("no section index found: %s", line.c_str());
646 return res;
647 }
648 constexpr int len {4};
649 std::string str = line.substr(pos, len);
650 if (str.length() != len) {
651 HLOGV("section index form incorrect: %s", str.c_str());
652 return res;
653 }
654 // section index is of the form "[xx]"
655 constexpr int firstDigit {1};
656 constexpr int numDigits {2};
657 str = str.substr(firstDigit, numDigits);
658 if (str[0] == ' ') {
659 // str = [ x], transform it to [xx]
660 str[0] = '0';
661 }
662 if (IsDigits(str)) {
663 res = std::stoll(str);
664 } else {
665 HLOGV("not digits: %s", str.c_str());
666 }
667 return res;
668 }
669
GetName(const std::string & line)670 const std::string ShdrFromReadelf::GetName(const std::string &line)
671 {
672 auto pos = line.find("]");
673 if (pos == std::string::npos) {
674 HLOGV("incorrect section line: %s", line.c_str());
675 return "";
676 }
677 ++pos;
678 std::string tmpLine = line.substr(pos, line.length() - pos);
679 auto strVec = StringSplit(tmpLine, " ");
680 std::string res {};
681 constexpr int index {1};
682 if (strVec.size() <= index) {
683 return res;
684 }
685 std::string str = strVec[index];
686 if (str[0] == '.') {
687 res = str;
688 }
689 return res;
690 }
691
GetAddress(const std::string & line)692 int64_t ShdrFromReadelf::GetAddress(const std::string &line)
693 {
694 int64_t res {-1};
695 auto pos = line.find("]");
696 if (pos == std::string::npos) {
697 HLOGV("incorrect section line: %s", line.c_str());
698 return res;
699 }
700 ++pos;
701 std::string tmpLine = line.substr(pos, line.length() - pos);
702 auto strVec = StringSplit(tmpLine, " ");
703 std::size_t index {3};
704 if (secName_ == "") {
705 --index;
706 }
707 if (strVec.size() <= index) {
708 return res;
709 }
710 std::string str = strVec[index];
711 if (IsHexDigits(str)) {
712 constexpr int base {16};
713 res = std::stoll(str, nullptr, base);
714 }
715 return res;
716 }
717
GetFileOffset(const std::string & line)718 int64_t ShdrFromReadelf::GetFileOffset(const std::string &line)
719 {
720 int64_t res {-1};
721 auto pos = line.find("]");
722 if (pos == std::string::npos) {
723 HLOGV("incorrect section line: %s", line.c_str());
724 return res;
725 }
726 ++pos;
727 std::string tmpLine = line.substr(pos, line.length() - pos);
728 auto strVec = StringSplit(tmpLine, " ");
729 std::size_t index {4};
730 if (secName_ == "") {
731 --index;
732 }
733 if (strVec.size() <= index) {
734 return res;
735 }
736 std::string str = strVec[index];
737 if (IsHexDigits(str)) {
738 constexpr int base {16};
739 res = std::stoll(str, nullptr, base);
740 }
741 return res;
742 }
743
GetSecSize(const std::string & line)744 int64_t ShdrFromReadelf::GetSecSize(const std::string &line)
745 {
746 int64_t res {-1};
747 auto pos = line.find("]");
748 if (pos == std::string::npos) {
749 HLOGV("incorrect section line: %s", line.c_str());
750 return res;
751 }
752 ++pos;
753 std::string tmpLine = line.substr(pos, line.length() - pos);
754 auto strVec = StringSplit(tmpLine, " ");
755 std::size_t index {5};
756 if (secName_ == "") {
757 --index;
758 }
759 if (strVec.size() <= index) {
760 return res;
761 }
762 std::string str = strVec[index];
763 if (IsHexDigits(str)) {
764 constexpr int base {16};
765 res = std::stoll(str, nullptr, base);
766 }
767 return res;
768 }
769
GetEntrySize(const std::string & line)770 int64_t ShdrFromReadelf::GetEntrySize(const std::string &line)
771 {
772 int64_t res {-1};
773 auto pos = line.find("]");
774 if (pos == std::string::npos) {
775 HLOGV("incorrect section line: %s", line.c_str());
776 return res;
777 }
778 ++pos;
779 std::string tmpLine = line.substr(pos, line.length() - pos);
780 auto strVec = StringSplit(tmpLine, " ");
781 std::size_t index {6};
782 if (secName_ == "") {
783 --index;
784 }
785 if (strVec.size() <= index) {
786 return res;
787 }
788 std::string str = strVec[index];
789 if (IsHexDigits(str)) {
790 constexpr int base {16};
791 res = std::stoll(str, nullptr, base);
792 }
793 return res;
794 }
795
GetLink(const std::string & line)796 int64_t ShdrFromReadelf::GetLink(const std::string &line)
797 {
798 int64_t res {-1};
799 auto pos = line.find("]");
800 if (pos == std::string::npos) {
801 HLOGV("incorrect section line: %s", line.c_str());
802 return res;
803 }
804 ++pos;
805 std::string tmpLine = line.substr(pos, line.length() - pos);
806 auto strVec = StringSplit(tmpLine, " ");
807 int index {-3};
808 if (strVec.size() + index < 0) {
809 return res;
810 }
811 std::string str = strVec[strVec.size() + index];
812 if (IsDigits(str)) {
813 res = std::stoll(str);
814 }
815 return res;
816 }
817
GetInfo(const std::string & line)818 int64_t ShdrFromReadelf::GetInfo(const std::string &line)
819 {
820 int64_t res {-1};
821 auto pos = line.find("]");
822 if (pos == std::string::npos) {
823 HLOGV("incorrect section line: %s", line.c_str());
824 return res;
825 }
826 ++pos;
827 std::string tmpLine = line.substr(pos, line.length() - pos);
828 auto strVec = StringSplit(tmpLine, " ");
829 int index {-2};
830 if (strVec.size() + index < 0) {
831 return res;
832 }
833 std::string str = strVec[strVec.size() + index];
834 if (IsDigits(str)) {
835 res = std::stoll(str);
836 }
837 return res;
838 }
839
GetAlign(const std::string & line)840 int64_t ShdrFromReadelf::GetAlign(const std::string &line)
841 {
842 int64_t res {-1};
843 auto pos = line.find("]");
844 if (pos == std::string::npos) {
845 HLOGV("incorrect section line: %s", line.c_str());
846 return res;
847 }
848 ++pos;
849 std::string tmpLine = line.substr(pos, line.length() - pos);
850 auto strVec = StringSplit(tmpLine, " ");
851 int index {-1};
852 if (strVec.size() + index < 0) {
853 return res;
854 }
855 std::string str = strVec[strVec.size() + index];
856 if (IsDigits(str)) {
857 res = std::stoll(str);
858 }
859 return res;
860 }
861
MakeUnique(const std::string & line)862 std::unique_ptr<PhdrFromReadelf> PhdrFromReadelf::MakeUnique(const std::string &line)
863 {
864 std::unique_ptr<PhdrFromReadelf> phdr {new (std::nothrow) PhdrFromReadelf()};
865 if (phdr == nullptr) {
866 HLOGV("PhdrFromReadelf() failed");
867 return nullptr;
868 }
869 if (!phdr->Init(line)) {
870 HLOGV("PhdrFromReadelf::Init(line) failed");
871 HLOGV(" line = %s", line.c_str());
872 return nullptr;
873 }
874 HLOGD("PhdrFromReadelf::MakeUnique() done");
875 return phdr;
876 }
877
Init(const std::string & line)878 bool PhdrFromReadelf::Init(const std::string &line)
879 {
880 auto offset = GetOffset(line);
881 if (offset == -1) {
882 HLOGV("PhdrFromReadelf::GetOffset(line) failed");
883 HLOGV(" line = %s", line.c_str());
884 return false;
885 }
886 offset_ = static_cast<uint64_t>(offset);
887 auto vaddr = GetVaddr(line);
888 if (vaddr == -1) {
889 HLOGV("PhdrFromReadelf::GetVaddr(line) failed");
890 HLOGV(" line = %s", line.c_str());
891 return false;
892 }
893 vaddr_ = static_cast<uint64_t>(vaddr);
894 auto paddr = GetPaddr(line);
895 if (paddr == -1) {
896 HLOGV("PhdrFromReadelf::GetPaddr(line) failed");
897 HLOGV(" line = %s", line.c_str());
898 return false;
899 }
900 paddr_ = static_cast<uint64_t>(paddr);
901 auto fileSize = GetFileSize(line);
902 if (fileSize == -1) {
903 HLOGV("PhdrFromReadelf::GetFileSize(line) failed");
904 HLOGV(" line = %s", line.c_str());
905 return false;
906 }
907 fileSize_ = static_cast<uint64_t>(fileSize);
908 auto align = GetAlign(line);
909 if (align == -1) {
910 HLOGV("PhdrFromReadelf::GetAlign(line) failed");
911 HLOGV(" line = %s", line.c_str());
912 }
913 secAlign_ = static_cast<uint64_t>(align);
914 return true;
915 }
916
GetOffset(const std::string & line)917 int64_t PhdrFromReadelf::GetOffset(const std::string &line)
918 {
919 int64_t res {-1};
920 auto strVec = StringSplit(line, " ");
921 constexpr int index {1};
922 if (strVec.size() <= index) {
923 HLOGV("short line: %s", line.c_str());
924 return res;
925 }
926 std::string str = strVec[index];
927 if (IsHexDigits(str)) {
928 constexpr int base {16};
929 res = std::stoll(str, nullptr, base);
930 } else {
931 HLOGV("not hex number: %s", str.c_str());
932 }
933 return res;
934 }
935
GetVaddr(const std::string & line)936 int64_t PhdrFromReadelf::GetVaddr(const std::string &line)
937 {
938 int64_t res {-1};
939 auto strVec = StringSplit(line, " ");
940 constexpr int index {2};
941 if (strVec.size() <= index) {
942 return res;
943 }
944 std::string str = strVec[index];
945 if (IsHexDigits(str)) {
946 constexpr int base {16};
947 res = std::stoll(str, nullptr, base);
948 }
949 return res;
950 }
951
GetPaddr(const std::string & line)952 int64_t PhdrFromReadelf::GetPaddr(const std::string &line)
953 {
954 int64_t res {-1};
955 auto strVec = StringSplit(line, " ");
956 constexpr int index {3};
957 if (strVec.size() <= index) {
958 return res;
959 }
960 std::string str = strVec[index];
961 if (IsHexDigits(str)) {
962 constexpr int base {16};
963 res = std::stoll(str, nullptr, base);
964 }
965 return res;
966 }
967
GetFileSize(const std::string & line)968 int64_t PhdrFromReadelf::GetFileSize(const std::string &line)
969 {
970 int64_t res {-1};
971 auto strVec = StringSplit(line, " ");
972 constexpr int index {4};
973 if (strVec.size() <= index) {
974 return res;
975 }
976 std::string str = strVec[index];
977 if (IsHexDigits(str)) {
978 HLOGD("program header file size: %s", str.c_str());
979 constexpr int base {16};
980 res = std::stoll(str, nullptr, base);
981 }
982 return res;
983 }
984
GetMemSize(const std::string & line)985 int64_t PhdrFromReadelf::GetMemSize(const std::string &line)
986 {
987 int64_t res {-1};
988 auto strVec = StringSplit(line, " ");
989 constexpr int index {5};
990 if (strVec.size() <= index) {
991 return res;
992 }
993 std::string str = strVec[index];
994 if (IsHexDigits(str)) {
995 constexpr int base {16};
996 res = std::stoll(str, nullptr, base);
997 }
998 return res;
999 }
1000
GetAlign(const std::string & line)1001 int64_t PhdrFromReadelf::GetAlign(const std::string &line)
1002 {
1003 int64_t res {-1};
1004 auto strVec = StringSplit(line, " ");
1005 constexpr int index {-1};
1006 if (strVec.size() + index < 0) {
1007 return res;
1008 }
1009 std::string str = strVec[strVec.size() + index];
1010 if (IsHexDigits(str)) {
1011 constexpr int base {16};
1012 res = std::stoll(str, nullptr, base);
1013 }
1014 return res;
1015 }
1016
MakeUnique(FILE * fp)1017 std::unique_ptr<EhdrFromReadelf> EhdrFromReadelf::MakeUnique(FILE *fp)
1018 {
1019 if (fp == nullptr) {
1020 HLOGE("param is null");
1021 return nullptr;
1022 }
1023 std::unique_ptr<EhdrFromReadelf> ehdr {new (std::nothrow) EhdrFromReadelf()};
1024 if (ehdr == nullptr) {
1025 HLOGV("EhdrFromReadelf() failed");
1026 return nullptr;
1027 }
1028 if (!ehdr->Init(fp)) {
1029 HLOGV("EhdrFromReadelf::Init(fp) failed:");
1030 return nullptr;
1031 }
1032 HLOGD("EhdrFromReadelf::MakeUnique() done");
1033 return ehdr;
1034 }
1035
Init(FILE * fp)1036 bool EhdrFromReadelf::Init(FILE *fp)
1037 {
1038 if (fp == nullptr) {
1039 HLOGE("param is null");
1040 return false;
1041 }
1042 int status {0};
1043 // drop header line
1044 GetNextLine(fp, &status);
1045 if (!GetMagic(fp)) {
1046 HLOGV("EhdrFromReadelf::InitMagic(fp) failed:");
1047 return false;
1048 }
1049 constexpr int numSkip {8};
1050 // drop unused 8 lines
1051 for (int count = 0; count < numSkip; ++count) {
1052 GetNextLine(fp, &status);
1053 }
1054 if (!GetEntryAddr(fp)) {
1055 HLOGV("EhdrFromReadelf::InitEntryAddr(fp) failed:");
1056 return false;
1057 }
1058 if (!GetPrgOffset(fp)) {
1059 HLOGV("EhdrFromReadelf::InitPrgOffset(fp) failed:");
1060 return false;
1061 }
1062 if (!GetSecOffset(fp)) {
1063 HLOGV("EhdrFromReadelf::InitSecOffset(fp) failed:");
1064 return false;
1065 }
1066 if (!GetFlag(fp)) {
1067 HLOGV("EhdrFromReadelf::InitFlag(fp) failed:");
1068 return false;
1069 }
1070 if (!GetEhdrSize(fp)) {
1071 HLOGV("EhdrFromReadelf::InitEhdrSize(fp) failed:");
1072 return false;
1073 }
1074 if (!GetPhdrSize(fp)) {
1075 HLOGV("EhdrFromReadelf::InitPhdrSize(fp) failed:");
1076 return false;
1077 }
1078 if (!GetNumPhdrs(fp)) {
1079 HLOGV("EhdrFromReadelf::InitNumPhdrs(fp) failed:");
1080 return false;
1081 }
1082 if (!GetShdrSize(fp)) {
1083 HLOGV("EhdrFromReadelf::InitShdrSize(fp) failed:");
1084 return false;
1085 }
1086 if (!GetNumShdrs(fp)) {
1087 HLOGV("EhdrFromReadelf::InitNumShdrs(fp) failed:");
1088 return false;
1089 }
1090 if (!GetShdrStrTabIdx(fp)) {
1091 HLOGV("EhdrFromReadelf::InitShdrStrTabIdx(fp) failed:");
1092 return false;
1093 }
1094 return true;
1095 }
1096
GetMagic(FILE * const fp)1097 bool EhdrFromReadelf::GetMagic(FILE * const fp)
1098 {
1099 if (fp == nullptr) {
1100 HLOGE("param is null");
1101 return false;
1102 }
1103 int status {0};
1104 std::string magicLine = GetNextLine(fp, &status);
1105 if (status == -1) {
1106 HLOGV("early end");
1107 return false;
1108 }
1109 auto tmp = StringSplit(magicLine, " ");
1110 std::vector<std::string> strVec {tmp.begin() + 1, tmp.end()};
1111 if (strVec.size() != EI_NIDENT) {
1112 HLOGV("line format incorrect:");
1113 HLOGV(" line = %s", magicLine.c_str());
1114 return false;
1115 }
1116 for (std::size_t count = 0; count < strVec.size(); ++count) {
1117 std::string valStr = strVec[count];
1118 constexpr int base {16};
1119 ehdrIdent_[count] = static_cast<unsigned char>(std::stoul(valStr, nullptr, base));
1120 }
1121 return true;
1122 }
1123
GetEntryAddr(FILE * const fp)1124 bool EhdrFromReadelf::GetEntryAddr(FILE * const fp)
1125 {
1126 int status {0};
1127 std::string entryLine = GetNextLine(fp, &status);
1128 if (status == -1) {
1129 HLOGV("early end");
1130 return false;
1131 }
1132 auto strVec = StringSplit(entryLine, " ");
1133 constexpr int len {2};
1134 if (strVec.size() != len) {
1135 HLOGV("line format incorrect:");
1136 HLOGV(" line = %s", entryLine.c_str());
1137 return false;
1138 }
1139 std::string entryStr = strVec.back();
1140 constexpr int base {16};
1141 prgEntryVaddr_ = static_cast<uint64_t>(std::stoull(entryStr, nullptr, base));
1142 return true;
1143 }
1144
GetPrgOffset(FILE * const fp)1145 bool EhdrFromReadelf::GetPrgOffset(FILE * const fp)
1146 {
1147 int status {0};
1148 std::string line = GetNextLine(fp, &status);
1149 if (status == -1) {
1150 HLOGV("early end");
1151 return false;
1152 }
1153 auto strVec = StringSplit(line, " ");
1154 constexpr int len {5};
1155 if (strVec.size() != len) {
1156 HLOGV("line format incorrect:");
1157 HLOGV(" line = %s", line.c_str());
1158 return false;
1159 }
1160 constexpr int valIndex {1};
1161 std::string valStr = strVec[valIndex];
1162 phdrOffset_ = static_cast<uint64_t>(std::stoull(valStr));
1163 return true;
1164 }
1165
GetSecOffset(FILE * const fp)1166 bool EhdrFromReadelf::GetSecOffset(FILE * const fp)
1167 {
1168 int status {0};
1169 std::string line = GetNextLine(fp, &status);
1170 if (status == -1) {
1171 HLOGV("early end");
1172 return false;
1173 }
1174 auto strVec = StringSplit(line, " ");
1175 constexpr int len {8};
1176 if (strVec.size() != len) {
1177 HLOGV("line format incorrect:");
1178 HLOGV(" line = %s", line.c_str());
1179 return false;
1180 }
1181 constexpr int valIndex {4};
1182 std::string valStr = strVec[valIndex];
1183 shdrOffset_ = static_cast<uint64_t>(std::stoull(valStr));
1184 return true;
1185 }
1186
GetFlag(FILE * const fp)1187 bool EhdrFromReadelf::GetFlag(FILE * const fp)
1188 {
1189 int status {0};
1190 std::string line = GetNextLine(fp, &status);
1191 if (status == -1) {
1192 HLOGV("early end");
1193 return false;
1194 }
1195 auto strVec = StringSplit(line, " ");
1196 constexpr int len {2};
1197 if (strVec.size() != len) {
1198 HLOGV("line format incorrect:");
1199 HLOGV(" line = %s", line.c_str());
1200 return false;
1201 }
1202 constexpr int valIndex {1};
1203 std::string valStr = strVec[valIndex];
1204 ehdrFlags_ = static_cast<uint32_t>(std::stoul(valStr));
1205 return true;
1206 }
1207
GetEhdrSize(FILE * const fp)1208 bool EhdrFromReadelf::GetEhdrSize(FILE * const fp)
1209 {
1210 int status {0};
1211 std::string line = GetNextLine(fp, &status);
1212 if (status == -1) {
1213 HLOGV("early end");
1214 return false;
1215 }
1216 auto strVec = StringSplit(line, " ");
1217 constexpr int len {6};
1218 if (strVec.size() != len) {
1219 HLOGV("line format incorrect:");
1220 HLOGV(" line = %s", line.c_str());
1221 return false;
1222 }
1223 constexpr int valIndex {4};
1224 std::string valStr = strVec[valIndex];
1225 ehdrSize_ = static_cast<uint16_t>(std::stoull(valStr));
1226 return true;
1227 }
1228
GetPhdrSize(FILE * const fp)1229 bool EhdrFromReadelf::GetPhdrSize(FILE * const fp)
1230 {
1231 int status {0};
1232 std::string line = GetNextLine(fp, &status);
1233 if (status == -1) {
1234 HLOGV("early end");
1235 return false;
1236 }
1237 auto strVec = StringSplit(line, " ");
1238 constexpr int len {6};
1239 if (strVec.size() != len) {
1240 HLOGV("line format incorrect:");
1241 HLOGV(" line = %s", line.c_str());
1242 return false;
1243 }
1244 constexpr int valIndex {4};
1245 std::string valStr = strVec[valIndex];
1246 phdrEntSize_ = static_cast<uint16_t>(std::stoull(valStr));
1247 return true;
1248 }
1249
GetNumPhdrs(FILE * const fp)1250 bool EhdrFromReadelf::GetNumPhdrs(FILE * const fp)
1251 {
1252 int status {0};
1253 std::string line = GetNextLine(fp, &status);
1254 if (status == -1) {
1255 HLOGV("early end");
1256 return false;
1257 }
1258 auto strVec = StringSplit(line, " ");
1259 constexpr int len {5};
1260 if (strVec.size() != len) {
1261 HLOGV("line format incorrect:");
1262 HLOGV(" line = %s", line.c_str());
1263 return false;
1264 }
1265 constexpr int valIndex {4};
1266 std::string valStr = strVec[valIndex];
1267 phdrNumEnts_ = static_cast<uint16_t>(std::stoull(valStr));
1268 return true;
1269 }
1270
GetShdrSize(FILE * const fp)1271 bool EhdrFromReadelf::GetShdrSize(FILE * const fp)
1272 {
1273 int status {0};
1274 std::string line = GetNextLine(fp, &status);
1275 if (status == -1) {
1276 HLOGV("early end");
1277 return false;
1278 }
1279 auto strVec = StringSplit(line, " ");
1280 constexpr int len {6};
1281 if (strVec.size() != len) {
1282 HLOGV("line format incorrect:");
1283 HLOGV(" line = %s", line.c_str());
1284 return false;
1285 }
1286 constexpr int valIndex {4};
1287 std::string valStr = strVec[valIndex];
1288 shdrEntSize_ = static_cast<uint16_t>(std::stoull(valStr));
1289 return true;
1290 }
1291
GetNumShdrs(FILE * const fp)1292 bool EhdrFromReadelf::GetNumShdrs(FILE * const fp)
1293 {
1294 int status {0};
1295 std::string line = GetNextLine(fp, &status);
1296 if (status == -1) {
1297 HLOGV("early end");
1298 return false;
1299 }
1300 auto strVec = StringSplit(line, " ");
1301 constexpr int len {5};
1302 if (strVec.size() != len) {
1303 HLOGV("line format incorrect:");
1304 HLOGV(" line = %s", line.c_str());
1305 return false;
1306 }
1307 constexpr int valIndex {4};
1308 std::string valStr = strVec[valIndex];
1309 shdrNumEnts_ = static_cast<uint16_t>(std::stoull(valStr));
1310 return true;
1311 }
1312
GetShdrStrTabIdx(FILE * const fp)1313 bool EhdrFromReadelf::GetShdrStrTabIdx(FILE * const fp)
1314 {
1315 int status {0};
1316 std::string line = GetNextLine(fp, &status);
1317 if (status == -1) {
1318 HLOGV("early end");
1319 return false;
1320 }
1321 auto strVec = StringSplit(line, " ");
1322 constexpr int len {6};
1323 if (strVec.size() != len) {
1324 HLOGV("line format incorrect:");
1325 HLOGV(" line = %s", line.c_str());
1326 return false;
1327 }
1328 constexpr int valIndex {5};
1329 std::string valStr = strVec[valIndex];
1330 shdrStrTabIdx_ = static_cast<uint16_t>(std::stoull(valStr));
1331 return true;
1332 }
1333
CompareElfHeader(const std::unique_ptr<ElfFileFromReadelf> & elfFileFromReadelf,const std::unique_ptr<ElfFile> & elfFile)1334 static bool CompareElfHeader(const std::unique_ptr<ElfFileFromReadelf> &elfFileFromReadelf,
1335 const std::unique_ptr<ElfFile> &elfFile)
1336 {
1337 const auto &ehdr1 = elfFile->ehdr_;
1338 const auto &ehdr2 = elfFileFromReadelf->ehdr_;
1339 if (MemCmp(ehdr1->ehdrIdent_, ehdr2->ehdrIdent_, EI_NIDENT) != EI_NIDENT) {
1340 return false;
1341 }
1342 if (ehdr1->ehdrSize_ != ehdr2->ehdrSize_) {
1343 return false;
1344 }
1345 if (ehdr1->phdrEntSize_ != ehdr2->phdrEntSize_) {
1346 return false;
1347 }
1348 if (ehdr1->phdrNumEnts_ != ehdr2->phdrNumEnts_) {
1349 return false;
1350 }
1351 if (ehdr1->shdrEntSize_ != ehdr2->shdrEntSize_) {
1352 return false;
1353 }
1354 if (ehdr1->shdrNumEnts_ != ehdr2->shdrNumEnts_) {
1355 return false;
1356 }
1357 if (ehdr1->shdrStrTabIdx_ != ehdr2->shdrStrTabIdx_) {
1358 return false;
1359 }
1360 if (ehdr1->ehdrFlags_ != ehdr2->ehdrFlags_) {
1361 return false;
1362 }
1363 if (ehdr1->prgEntryVaddr_ != ehdr2->prgEntryVaddr_) {
1364 return false;
1365 }
1366 if (ehdr1->phdrOffset_ != ehdr2->phdrOffset_) {
1367 return false;
1368 }
1369 if (ehdr1->shdrOffset_ != ehdr2->shdrOffset_) {
1370 return false;
1371 }
1372 return true;
1373 }
1374
CompareSecHeaders(const std::unique_ptr<ElfFileFromReadelf> & elfFileFromReadelf,const std::unique_ptr<ElfFile> & elfFile)1375 static bool CompareSecHeaders(const std::unique_ptr<ElfFileFromReadelf> &elfFileFromReadelf,
1376 const std::unique_ptr<ElfFile> &elfFile)
1377 {
1378 const auto &shdrs1 = elfFile->shdrs_;
1379 const auto &shdrs2 = elfFileFromReadelf->shdrs_;
1380 std::size_t totalShdrs1 = shdrs1.size();
1381 std::size_t totalShdrs2 = shdrs2.size();
1382 HLOGV("number of section headers from elf_parser: %zu", totalShdrs1);
1383 HLOGV("number of section headers from readelf: %zu", totalShdrs2);
1384 if (totalShdrs1 != totalShdrs2) {
1385 return false;
1386 }
1387 return true;
1388 }
1389
ComparePrgHeaders(const std::unique_ptr<ElfFileFromReadelf> & elfFileFromReadelf,const std::unique_ptr<ElfFile> & elfFile)1390 static bool ComparePrgHeaders(const std::unique_ptr<ElfFileFromReadelf> &elfFileFromReadelf,
1391 const std::unique_ptr<ElfFile> &elfFile)
1392 {
1393 const auto &phdrs1 = elfFile->phdrs_;
1394 const auto &phdrs2 = elfFileFromReadelf->phdrs_;
1395 std::size_t totalPhdrs1 = phdrs1.size();
1396 std::size_t totalPhdrs2 = phdrs2.size();
1397 HLOGV("number of program headers from elf_parser: %zu", totalPhdrs1);
1398 HLOGV("number of program headers from readelf: %zu", totalPhdrs2);
1399 if (totalPhdrs1 != totalPhdrs2) {
1400 return false;
1401 }
1402 return true;
1403 }
1404
1405 class ElfParserTest : public testing::Test {
1406 public:
1407 static void SetUpTestCase(void);
1408 static void TearDownTestCase(void);
1409 void SetUp();
1410 void TearDown();
1411 void PrintElfHeader(const std::unique_ptr<ElfHeader> &ehdr) const;
1412 void PrintSecHeader(const std::unique_ptr<SectionHeader> &shdr) const;
1413 void PrintSecHeaders(const ElfFile::SecHeaderTableType &shdrs) const;
1414 std::unique_ptr<ElfFile> elfFile64_ {nullptr};
1415 std::unique_ptr<ElfFile> elfFile32_ {nullptr};
1416 std::unique_ptr<ElfFileFromReadelf> elfFile64FromReadelf_ {nullptr};
1417 std::unique_ptr<ElfFileFromReadelf> elfFile32FromReadelf_ {nullptr};
1418 };
1419
SetUpTestCase()1420 void ElfParserTest::SetUpTestCase() {}
1421
TearDownTestCase()1422 void ElfParserTest::TearDownTestCase() {}
1423
SetUp()1424 void ElfParserTest::SetUp()
1425 {
1426 elfFile64_ = ElfFile::MakeUnique(file64);
1427 ASSERT_FALSE(elfFile64_ == nullptr);
1428 HLOGD("elfFile64_ setup");
1429 elfFile32_ = ElfFile::MakeUnique(file32);
1430 ASSERT_FALSE(elfFile32_ == nullptr);
1431 HLOGD("elfFile32_ setup");
1432 elfFile64FromReadelf_ = ElfFileFromReadelf::MakeUnique(ElfFileFromReadelf::ElfFileType::ELF64);
1433 ASSERT_FALSE(elfFile64FromReadelf_ == nullptr);
1434 HLOGD("elfFile64FromReadelf_ setup");
1435 elfFile32FromReadelf_ = ElfFileFromReadelf::MakeUnique(ElfFileFromReadelf::ElfFileType::ELF32);
1436 ASSERT_FALSE(elfFile32FromReadelf_ == nullptr);
1437 HLOGD("elfFile32FromReadelf_ setup");
1438 }
1439
TearDown()1440 void ElfParserTest::TearDown() {}
1441
1442 HWTEST_F(ElfParserTest, ParseElfHeader, TestSize.Level1)
1443 {
1444 EXPECT_TRUE(CompareElfHeader(elfFile64FromReadelf_, elfFile64_));
1445 EXPECT_TRUE(CompareElfHeader(elfFile32FromReadelf_, elfFile32_));
1446 }
1447
1448 HWTEST_F(ElfParserTest, ParseSecHeaders, TestSize.Level1)
1449 {
1450 EXPECT_TRUE(CompareSecHeaders(elfFile64FromReadelf_, elfFile64_));
1451 EXPECT_TRUE(CompareSecHeaders(elfFile32FromReadelf_, elfFile32_));
1452 }
1453
1454 HWTEST_F(ElfParserTest, ParsePrgHeaders, TestSize.Level1)
1455 {
1456 EXPECT_TRUE(ComparePrgHeaders(elfFile64FromReadelf_, elfFile64_));
1457 EXPECT_TRUE(ComparePrgHeaders(elfFile32FromReadelf_, elfFile32_));
1458 }
1459 // This is not code HWTEST_F(ElfParserTest, ParseSymTable, TestSize.Level1)
1460 // This is not code {
1461 // This is not code EXPECT_TRUE(CompareSymTable(elfFile64FromReadelf_, elfFile64_));
1462 // This is not code EXPECT_TRUE(CompareSymTable(elfFile32FromReadelf_, elfFile32_));
1463 // This is not code }
1464 // This is not code
1465 // This is not code HWTEST_F(ElfParserTest, ParseDynSymTable, TestSize.Level1)
1466 // This is not code {
1467 // This is not code EXPECT_TRUE(CompareDynSymTable(elfFile64FromReadelf_, elfFile64_));
1468 // This is not code EXPECT_TRUE(CompareDynSymTable(elfFile32FromReadelf_, elfFile32_));
1469 // This is not code }
1470 } // namespace UnitTest
1471 } // namespace HiPerf
1472 } // namespace Developtools
1473 } // namespace OHOS
1474