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 "kernel_symbol_info.h" 16 17#include <cstring> 18#include <fstream> 19#include <sstream> 20 21namespace OHOS { 22namespace Developtools { 23namespace Hiebpf { 24void KernelSymbolInfo::GetSymbol(const std::string &line, SymbolItem &symbol) 25{ 26 std::stringstream str(line.c_str()); 27 str >> std::hex >> symbol.value_; 28 str >> symbol.type_; 29 // only keep text or weak type 30 if (std::strchr("TtWw", symbol.type_)) { 31 symbol.type_ = 'T'; 32 } else { 33 return; 34 } 35 str >> symbol.name_; 36} 37 38void KernelSymbolInfo::GetBinary(const std::vector<SymbolItem> &symbolItems, 39 uint64_t vaddrStart, 40 uint64_t vaddrEnd, 41 uint32_t strTabLen, 42 std::vector<uint8_t> &buf) 43{ 44 // (value + size + nameOffset) 45 uint32_t symTabLen = (sizeof(uint64_t) + sizeof(uint32_t) + sizeof(uint32_t)) * 46 symbolItems.size(); 47 // vaddrStart + vaddrEnd + symTbaLen + strTabLen + symTabData + strTabData 48 uint32_t dataLen = sizeof(uint64_t) + sizeof(uint64_t) + sizeof(uint32_t) + sizeof(uint32_t) 49 + symTabLen + strTabLen; 50 buf.resize(dataLen); 51 52 uint8_t *p = buf.data(); 53 *(reinterpret_cast<uint64_t *>(p)) = vaddrStart; 54 p += sizeof(uint64_t); 55 *(reinterpret_cast<uint64_t *>(p)) = vaddrEnd; 56 p += sizeof(uint64_t); 57 *(reinterpret_cast<uint32_t *>(p)) = symTabLen; 58 p += sizeof(uint32_t); 59 *(reinterpret_cast<uint32_t *>(p)) = strTabLen; 60 p += sizeof(uint32_t); 61 62 uint32_t strTabSize = 0; 63 uint8_t *pStrTab = p + symTabLen; 64 for (auto &symbol : symbolItems) { 65 *(reinterpret_cast<uint64_t *>(p)) = symbol.value_; 66 p += sizeof(uint64_t); 67 *(reinterpret_cast<uint32_t *>(p)) = symbol.size_; 68 p += sizeof(uint32_t); 69 *(reinterpret_cast<uint32_t *>(p)) = strTabSize; 70 p += sizeof(uint32_t); 71 72 std::copy(symbol.name_.c_str(), 73 symbol.name_.c_str() + symbol.name_.size() + 1, 74 pStrTab + strTabSize); 75 strTabSize += symbol.name_.size() + 1; 76 } 77} 78 79uint32_t KernelSymbolInfo::GetSymbolData(std::vector<uint8_t> &buf) 80{ 81 buf.clear(); 82 buf.reserve(DEFAULT_BUFF_SIZE); 83 84 std::ifstream file(KALLSYMS_PATH); 85 std::string line; 86 std::getline(file, line); 87 SymbolItem prevSymbol; 88 GetSymbol(line, prevSymbol); 89 uint64_t vaddrStart = prevSymbol.value_; 90 91 std::vector<SymbolItem> symbolItems; 92 uint32_t strTabLen = 0; 93 SymbolItem currSymbol; 94 while (std::getline(file, line)) { 95 GetSymbol(line, currSymbol); 96 if (prevSymbol.value_ >= currSymbol.value_) { 97 continue; // duplicated or wrong 98 } 99 if (prevSymbol.type_ == 'T') { 100 prevSymbol.size_ = currSymbol.value_ - prevSymbol.value_; 101 symbolItems.emplace_back(prevSymbol); 102 strTabLen += prevSymbol.name_.size() + 1; 103 } 104 prevSymbol = currSymbol; 105 } 106 file.close(); 107 if (prevSymbol.type_ == 'T') { 108 symbolItems.emplace_back(prevSymbol); 109 strTabLen += prevSymbol.name_.size() + 1; 110 } 111 if (symbolItems.empty()) { 112 return 0; 113 } 114 115 uint64_t vaddrEnd = prevSymbol.value_ + prevSymbol.size_; 116 GetBinary(symbolItems, vaddrStart, vaddrEnd, strTabLen, buf); 117 return buf.size(); 118} 119} // namespace Hiebpf 120} // namespace Developtools 121} // namespace OHOS