• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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