1 /*
2 * Copyright (c) Huawei Technologies Co., Ltd. 2022. All rights reserved.
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 #include "elf_symbol_info.h"
16
17 #include <limits>
18
19 #include "elf_file.h"
20 #include "hhlog.h"
21
22 namespace OHOS {
23 namespace Developtools {
24 namespace Hiebpf {
GetSymbolTable(const std::string & fileName,ElfSymbolTable & symbolTable)25 bool ElfSymbolInfo::GetSymbolTable(const std::string &fileName, ElfSymbolTable &symbolTable)
26 {
27 std::unique_ptr<ElfFile> elfFile = ElfFile::MakeUnique(fileName);
28 CHECK_NOTNULL(elfFile, false, "elf '%s' load failed\n", fileName.c_str());
29
30 // get .text
31 symbolTable.textVaddr_ = (std::numeric_limits<uint64_t>::max)();
32 for (auto &phdr : elfFile->phdrs_) {
33 if ((phdr->type_ == PT_LOAD) && (phdr->flags_ & PF_X)) {
34 // find the min addr
35 if (symbolTable.textVaddr_ != (std::min)(symbolTable.textVaddr_, phdr->vaddr_)) {
36 symbolTable.textVaddr_ = (std::min)(symbolTable.textVaddr_, phdr->vaddr_);
37 symbolTable.textOffset_ = phdr->offset_;
38 }
39 }
40 }
41 CHECK_TRUE(symbolTable.textVaddr_ != (std::numeric_limits<uint64_t>::max)(), false, "get text vaddr failed");
42
43 const std::string symTab {".symtab"};
44 if (elfFile->shdrs_.find(symTab) != elfFile->shdrs_.end()) {
45 // get .symtab
46 const auto &shdr = elfFile->shdrs_[symTab];
47 const uint8_t *data = elfFile->GetSectionData(shdr->secIndex_);
48 CHECK_NOTNULL(data, false, "get section data failed");
49 symbolTable.symTable_.resize(shdr->secSize_);
50 std::copy(data, data + shdr->secSize_, symbolTable.symTable_.data());
51 symbolTable.symEntSize_ = shdr->secEntrySize_;
52
53 // get .strtab
54 const std::string strTab {".strtab"};
55 CHECK_TRUE(elfFile->shdrs_.find(strTab) != elfFile->shdrs_.end(), false, "get symbol tab failed");
56 const auto &strshdr = elfFile->shdrs_[strTab];
57 data = elfFile->GetSectionData(strshdr->secIndex_);
58 CHECK_NOTNULL(data, false, "get section data failed");
59 symbolTable.strTable_.resize(strshdr->secSize_);
60 std::copy(data, data + strshdr->secSize_, symbolTable.strTable_.data());
61 } else {
62 // get .dynsym
63 const std::string dynSym {".dynsym"};
64 CHECK_TRUE(elfFile->shdrs_.find(dynSym) != elfFile->shdrs_.end(), false, "get symbol tab failed");
65 const auto &shdr = elfFile->shdrs_[dynSym];
66 const uint8_t *data = elfFile->GetSectionData(shdr->secIndex_);
67 CHECK_NOTNULL(data, false, "get section data failed");
68 symbolTable.symTable_.resize(shdr->secSize_);
69 std::copy(data, data + shdr->secSize_, symbolTable.symTable_.data());
70 symbolTable.symEntSize_ = shdr->secEntrySize_;
71
72 // get .dynstr
73 const std::string dynStr {".dynstr"};
74 CHECK_TRUE(elfFile->shdrs_.find(dynStr) != elfFile->shdrs_.end(), false, "get symbol tab failed");
75 const auto &strshdr = elfFile->shdrs_[dynStr];
76 data = elfFile->GetSectionData(strshdr->secIndex_);
77 CHECK_NOTNULL(data, false, "get section data failed");
78 symbolTable.strTable_.resize(strshdr->secSize_);
79 std::copy(data, data + strshdr->secSize_, symbolTable.strTable_.data());
80 }
81 CHECK_TRUE(symbolTable.strTable_.size() != 0 && symbolTable.symTable_.size() != 0, false,
82 "get strTable_ or symTable failed");
83 symbolTable.fileName_ = fileName;
84
85 return true;
86 }
87
GetBinary(const ElfSymbolTable & symbolTable,std::vector<uint8_t> & buf)88 uint32_t ElfSymbolInfo::GetBinary(const ElfSymbolTable &symbolTable, std::vector<uint8_t> &buf)
89 {
90 // strTabLen+symTabLen+fileNameLen
91 uint32_t fixLen = sizeof(symbolTable.textVaddr_) + sizeof(symbolTable.textOffset_) +
92 sizeof(uint32_t) + sizeof(uint32_t) + sizeof(uint32_t) + sizeof(uint32_t);
93 uint32_t len = fixLen + symbolTable.strTable_.size() + symbolTable.symTable_.size() +
94 symbolTable.fileName_.size() + 1;
95 buf.resize(len);
96
97 const uint8_t *rp = reinterpret_cast<const uint8_t *>(&symbolTable);
98 uint8_t *wp = buf.data();
99 std::copy(rp, rp + sizeof(symbolTable.textVaddr_) + sizeof(symbolTable.textOffset_), wp);
100 wp += sizeof(symbolTable.textVaddr_) + sizeof(symbolTable.textOffset_);
101 *(reinterpret_cast<uint32_t *>(wp)) = symbolTable.strTable_.size(); // strTabLen
102 wp += sizeof(uint32_t);
103 *(reinterpret_cast<uint32_t *>(wp)) = symbolTable.symTable_.size(); // symTabLen
104 wp += sizeof(uint32_t);
105 *(reinterpret_cast<uint32_t *>(wp)) = symbolTable.fileName_.size() + 1; // fileNameLen
106 wp += sizeof(uint32_t);
107 *(reinterpret_cast<uint32_t *>(wp)) = symbolTable.symEntSize_; // symEntLen
108 wp += sizeof(uint32_t);
109 std::copy(symbolTable.strTable_.data(),
110 symbolTable.strTable_.data() + symbolTable.strTable_.size(), wp);
111 wp += symbolTable.strTable_.size();
112 std::copy(symbolTable.symTable_.data(),
113 symbolTable.symTable_.data() + symbolTable.symTable_.size(), wp);
114 wp += symbolTable.symTable_.size();
115 std::copy(symbolTable.fileName_.c_str(),
116 symbolTable.fileName_.c_str() + symbolTable.fileName_.size() + 1, wp); // fileName
117
118 return buf.size();
119 }
120 } // namespace Hiebpf
121 } // namespace Developtools
122 } // namespace OHOS