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