1 /* 2 * Copyright (c) 2023 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 #ifndef DFX_ELF_PARSER_H 16 #define DFX_ELF_PARSER_H 17 18 #include <cstddef> 19 #if is_mingw 20 #include "dfx_nonlinux_define.h" 21 #else 22 #include <elf.h> 23 #include <link.h> 24 #endif 25 #include <map> 26 #include <memory> 27 #include <stdint.h> 28 #include <string> 29 #include <sys/stat.h> 30 #include <sys/types.h> 31 #include <set> 32 #include <unistd.h> 33 #include <unordered_map> 34 #include <vector> 35 36 #include "dfx_define.h" 37 #include "dfx_elf_define.h" 38 #include "dfx_mmap.h" 39 #include "dfx_symbol.h" 40 #include "unwind_context.h" 41 42 namespace OHOS { 43 namespace HiviewDFX { 44 class ElfParser { 45 public: ElfParser(const std::shared_ptr<DfxMmap> & mmap)46 ElfParser(const std::shared_ptr<DfxMmap>& mmap) : mmap_(mmap) {} 47 virtual ~ElfParser() = default; 48 49 virtual bool InitHeaders() = 0; GetArchType()50 virtual ArchType GetArchType() { return archType_; } 51 virtual uint64_t GetElfSize(); GetLoadBias()52 virtual int64_t GetLoadBias() { return loadBias_; } GetStartVaddr()53 virtual uint64_t GetStartVaddr() { return startVaddr_; } GetEndVaddr()54 virtual uint64_t GetEndVaddr() { return endVaddr_; } GetStartOffset()55 virtual uint64_t GetStartOffset() { return startOffset_; } 56 virtual std::string GetElfName() = 0; 57 virtual uintptr_t GetGlobalPointer() = 0; 58 virtual const std::set<ElfSymbol>& GetFuncSymbols() = 0; 59 virtual bool GetSectionInfo(ShdrInfo& shdr, const uint32_t idx); 60 virtual bool GetSectionInfo(ShdrInfo& shdr, const std::string& secName); 61 virtual bool GetSectionData(unsigned char *buf, uint64_t size, std::string secName); 62 virtual bool GetFuncSymbolByAddr(uint64_t addr, ElfSymbol& elfSymbol) = 0; GetPtLoads()63 const std::unordered_map<uint64_t, ElfLoadInfo>& GetPtLoads() {return ptLoads_;} 64 bool Read(uintptr_t pos, void *buf, size_t size); 65 const GnuDebugDataHdr& GetGnuDebugDataHdr() const; 66 std::string GetBuildId(); 67 static std::string ParseHexBuildId(uint64_t noteAddr, uint64_t noteSize); 68 protected: 69 size_t MmapSize(); 70 template <typename EhdrType, typename PhdrType, typename ShdrType> 71 bool ParseAllHeaders(); 72 template <typename EhdrType> 73 bool ParseElfHeaders(const EhdrType& ehdr); 74 template <typename EhdrType, typename PhdrType> 75 bool ParseProgramHeaders(const EhdrType& ehdr); 76 template <typename EhdrType, typename ShdrType> 77 bool ExtractSectionHeadersInfo(const EhdrType& ehdr, ShdrType& shdr); 78 template <typename EhdrType, typename ShdrType> 79 bool ParseSectionHeaders(const EhdrType& ehdr); 80 template <typename SymType> 81 bool IsFunc(const SymType sym); 82 template <typename SymType> 83 bool ParseFuncSymbols(); 84 template <typename SymType> 85 bool ParseFuncSymbols(const ElfShdr& shdr); 86 template <typename SymType> 87 bool ParseFuncSymbolName(const ShdrInfo& linkShdr, SymType sym, std::string& nameStr); 88 template <typename SymType> 89 bool ParseFuncSymbolByAddr(uint64_t addr, ElfSymbol& elfSymbol); 90 template <typename DynType> 91 bool ParseElfDynamic(); 92 template <typename DynType> 93 bool ParseElfName(); 94 bool ParseStrTab(std::string& nameStr, const uint64_t offset, const uint64_t size); 95 bool GetSectionNameByIndex(std::string& nameStr, const uint32_t name); 96 template <typename SymType> 97 bool ReadSymType(const ElfShdr& shdr, const uint32_t idx, SymType& sym); 98 std::string ToReadableBuildId(const std::string& buildIdHex); 99 100 protected: 101 std::set<ElfSymbol> funcSymbols_; 102 uint64_t dynamicOffset_ = 0; 103 uintptr_t dtPltGotAddr_ = 0; 104 uintptr_t dtStrtabAddr_ = 0; 105 uintptr_t dtStrtabSize_ = 0; 106 uintptr_t dtSonameOffset_ = 0; 107 std::string soname_ = ""; 108 GnuDebugDataHdr gnuDebugDataHdr_; 109 110 private: 111 std::shared_ptr<DfxMmap> mmap_; 112 ArchType archType_ = ARCH_UNKNOWN; 113 uint64_t elfSize_ = 0; 114 int64_t loadBias_ = 0; 115 uint64_t startVaddr_ = static_cast<uint64_t>(-1); 116 uint64_t startOffset_ = 0; 117 uint64_t endVaddr_ = 0; 118 std::vector<ElfShdr> symShdrs_; 119 std::map<std::pair<uint32_t, const std::string>, ShdrInfo> shdrInfoPairs_; 120 std::unordered_map<uint64_t, ElfLoadInfo> ptLoads_; 121 std::string sectionNames_; 122 }; 123 124 class ElfParser32 : public ElfParser { 125 public: ElfParser32(const std::shared_ptr<DfxMmap> & mmap)126 ElfParser32(const std::shared_ptr<DfxMmap>& mmap) : ElfParser(mmap) {} 127 virtual ~ElfParser32() = default; 128 bool InitHeaders() override; 129 std::string GetElfName() override; 130 uintptr_t GetGlobalPointer() override; 131 const std::set<ElfSymbol>& GetFuncSymbols() override; 132 bool GetFuncSymbolByAddr(uint64_t addr, ElfSymbol& elfSymbol) override; 133 }; 134 135 class ElfParser64 : public ElfParser { 136 public: ElfParser64(const std::shared_ptr<DfxMmap> & mmap)137 ElfParser64(const std::shared_ptr<DfxMmap>& mmap) : ElfParser(mmap) {} 138 virtual ~ElfParser64() = default; 139 bool InitHeaders() override; 140 std::string GetElfName() override; 141 uintptr_t GetGlobalPointer() override; 142 const std::set<ElfSymbol>& GetFuncSymbols() override; 143 bool GetFuncSymbolByAddr(uint64_t addr, ElfSymbol& elfSymbol) override; 144 }; 145 146 } // namespace HiviewDFX 147 } // namespace OHOS 148 #endif 149