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