• 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 <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