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 for (uint64_t curPos = 0; curPos < secSize; curPos += entrySize) {
90 char *symBuf = const_cast<char *>(secBuf + curPos);
91 /*
92 not >= , change to >
93 Section Headers:
94 [Nr] Name Type Address Offset
95 Size EntSize Flags Link Info Align
96 [ 0] NULL 0000000000000000 00000000
97 0000000000000000 0000000000000000 0 0 0
98 [ 1] .text NOBITS 000000009c868f20 00000000
99 0000000000000164 0000000000000000 AX 0 0 4096
100 [ 2] .strtab STRTAB 0000000000000000 00000040
101 0000000000000042 0000000000000000 0 0 4096
102 [ 3] .symtab SYMTAB 0000000000000000 00000082
103 0000000000000030 0000000000000018 2 1 8
104 [ 4] .debug_frame PROGBITS 0000000000000000 000000b2
105 00000000000000c8 0000000000000000 0 0 8
106 [ 5] .shstrtab STRTAB 0000000000000000 0000017a
107 000000000000002e 0000000000000000 0 0 1
108
109 Symbol table '.symtab' contains 2 entries:
110 Num: Value Size Type Bind Vis Ndx Name
111 0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND
112 1: 000000009c868f20 356 FUNC GLOBAL DEFAULT 1
113 */
114 if ((curPos + entrySize) > secSize) {
115 break;
116 }
117 std::unique_ptr<ElfSymbol> sym = ElfSymbol::MakeUnique(symBuf, entrySize);
118 if (sym == nullptr) {
119 HLOGE("Error in SymbolTable::MakeUnique(): ElfSymbol::MakeUnique() failed");
120 return nullptr;
121 }
122 symTable->symbols_.emplace_back(std::move(sym));
123 }
124 return symTable;
125 }
126 } // namespace HiPerf
127 } // namespace Developtools
128 } // namespace OHOS
129