• 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 <elf_parser.h>
17 
18 using namespace OHOS::Developtools::HiPerf::ELF;
19 namespace OHOS {
20 namespace Developtools {
21 namespace HiPerf {
MakeUnique(char * const symBuf,const std::size_t bufSize)22 std::unique_ptr<ElfSymbol> ElfSymbol::MakeUnique(char * const symBuf, const std::size_t bufSize)
23 {
24     std::unique_ptr<ElfSymbol> sym {new (std::nothrow) ElfSymbol()};
25     if (sym == nullptr) {
26         HLOGE("Error in ElfSymbol::MakeUnique(): ElfSymbol::ElfSymbol() failed");
27         return nullptr;
28     }
29     if (!sym->Init(symBuf, bufSize)) {
30         HLOGE("ElfSymbol::Init(symBuf, bufSize) failed");
31         DumpSymBuf(symBuf, bufSize);
32         return nullptr;
33     }
34     return sym;
35 }
36 
ParseElf32Symbol(char * const symBuf)37 bool ElfSymbol::ParseElf32Symbol(char * const symBuf)
38 {
39     uint32_t *u4Buf = reinterpret_cast<uint32_t *>(symBuf);
40     constexpr uint32_t nameOffset {0};
41     nameIndex_ = u4Buf[nameOffset];
42     constexpr uint32_t valueOffset {1};
43     symValue_ = u4Buf[valueOffset];
44     constexpr uint32_t sizeOffset {2};
45     symSize_ = u4Buf[sizeOffset];
46     constexpr uint32_t infoOffset {12};
47     symInfo_ = symBuf[infoOffset];
48     constexpr uint32_t otherInfoOffset {13};
49     symOtherInfo_ = symBuf[otherInfoOffset];
50     uint16_t *u2Buf = reinterpret_cast<uint16_t *>(symBuf);
51     constexpr uint32_t secOffset {7};
52     secIndex_ = u2Buf[secOffset];
53     return true;
54 }
55 
ParseElf64Symbol(char * const symBuf)56 bool ElfSymbol::ParseElf64Symbol(char * const symBuf)
57 {
58     uint32_t *u4Buf = reinterpret_cast<uint32_t *>(symBuf);
59     constexpr uint32_t nameOffset {0};
60     nameIndex_ = u4Buf[nameOffset];
61     constexpr uint32_t infoOffset {4};
62     symInfo_ = symBuf[infoOffset];
63     constexpr uint32_t otherInfoOffset {5};
64     symOtherInfo_ = symBuf[otherInfoOffset];
65     uint16_t *u2Buf = reinterpret_cast<uint16_t *>(symBuf);
66     constexpr uint32_t secOffset {3};
67     secIndex_ = u2Buf[secOffset];
68     uint64_t *u8Buf = reinterpret_cast<uint64_t *>(symBuf);
69     constexpr uint32_t valueOffset {1};
70     symValue_ = u8Buf[valueOffset];
71     constexpr uint32_t sizeOffset {2};
72     symSize_ = u8Buf[sizeOffset];
73     return true;
74 }
75 
MakeUnique(const std::string & symNamesStr,const char * const secBuf,const uint64_t secSize,const uint64_t entrySize)76 std::unique_ptr<SymbolTable> SymbolTable::MakeUnique(const std::string &symNamesStr,
77                                                      const char * const secBuf,
78                                                      const uint64_t secSize,
79                                                      const uint64_t entrySize)
80 {
81     std::unique_ptr<SymbolTable> symTable {new (std::nothrow) SymbolTable(symNamesStr)};
82     if (symNamesStr.empty()) {
83         HLOGE("symNamesStr is empty");
84     }
85     if (symTable == nullptr) {
86         HLOGE("Error in SymbleTable::MakeUnique(): SymbleTable::SymbolTable() failed");
87         return nullptr;
88     }
89     char *symBuf = const_cast<char *>(secBuf);
90     for (uint64_t curPos = 0; curPos < secSize; curPos += entrySize) {
91         symBuf = const_cast<char *>(secBuf + curPos);
92         /*
93             not >= , change to >
94             Section Headers:
95             [Nr] Name              Type             Address           Offset
96                 Size              EntSize          Flags  Link  Info  Align
97             [ 0]                   NULL             0000000000000000  00000000
98                 0000000000000000  0000000000000000           0     0     0
99             [ 1] .text             NOBITS           000000009c868f20  00000000
100                 0000000000000164  0000000000000000  AX       0     0     4096
101             [ 2] .strtab           STRTAB           0000000000000000  00000040
102                 0000000000000042  0000000000000000           0     0     4096
103             [ 3] .symtab           SYMTAB           0000000000000000  00000082
104                 0000000000000030  0000000000000018           2     1     8
105             [ 4] .debug_frame      PROGBITS         0000000000000000  000000b2
106                 00000000000000c8  0000000000000000           0     0     8
107             [ 5] .shstrtab         STRTAB           0000000000000000  0000017a
108                 000000000000002e  0000000000000000           0     0     1
109 
110             Symbol table '.symtab' contains 2 entries:
111             Num:    Value          Size Type    Bind   Vis      Ndx Name
112                 0: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT  UND
113                 1: 000000009c868f20   356 FUNC    GLOBAL DEFAULT    1
114         */
115         if ((curPos + entrySize) > secSize) {
116             break;
117         }
118         std::unique_ptr<ElfSymbol> sym = ElfSymbol::MakeUnique(symBuf, entrySize);
119         if (sym == nullptr) {
120             HLOGE("Error in SymbolTable::MakeUnique(): ElfSymbol::MakeUnique() failed");
121             return nullptr;
122         }
123         symTable->symbols_.emplace_back(std::move(sym));
124     }
125     return symTable;
126 }
127 } // namespace HiPerf
128 } // namespace Developtools
129 } // namespace OHOS