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