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 <unistd.h> 32 #include <unordered_map> 33 #include <vector> 34 35 #include "dfx_define.h" 36 #include "dfx_elf_define.h" 37 #include "dfx_mmap.h" 38 #include "dfx_symbol.h" 39 #include "unwind_context.h" 40 41 namespace OHOS { 42 namespace HiviewDFX { 43 class ElfParser { 44 public: ElfParser(const std::shared_ptr<DfxMmap> & mmap)45 ElfParser(const std::shared_ptr<DfxMmap>& mmap) : mmap_(mmap) {} 46 virtual ~ElfParser() = default; 47 48 virtual bool InitHeaders() = 0; GetArchType()49 virtual ArchType GetArchType() { return archType_; } 50 virtual uint64_t GetElfSize(); GetLoadBias()51 virtual int64_t GetLoadBias() { return loadBias_; } GetStartVaddr()52 virtual uint64_t GetStartVaddr() { return startVaddr_; } GetEndVaddr()53 virtual uint64_t GetEndVaddr() { return endVaddr_; } GetStartOffset()54 virtual uint64_t GetStartOffset() { return startOffset_; } 55 virtual std::string GetElfName() = 0; 56 virtual uintptr_t GetGlobalPointer() = 0; 57 virtual const std::vector<ElfSymbol>& GetElfSymbols(bool isFunc) = 0; 58 virtual bool GetSectionInfo(ShdrInfo& shdr, const uint32_t idx); 59 virtual bool GetSectionInfo(ShdrInfo& shdr, const std::string& secName); 60 virtual bool GetSectionData(unsigned char *buf, uint64_t size, std::string secName); 61 virtual bool GetElfSymbolByAddr(uint64_t addr, ElfSymbol& elfSymbol) = 0; GetPtLoads()62 const std::unordered_map<uint64_t, ElfLoadInfo>& GetPtLoads() {return ptLoads_;} 63 bool Read(uintptr_t pos, void *buf, size_t size); 64 std::shared_ptr<MiniDebugInfo> GetMiniDebugInfo(); 65 protected: 66 size_t MmapSize(); 67 template <typename EhdrType, typename PhdrType, typename ShdrType> 68 bool ParseAllHeaders(); 69 template <typename EhdrType> 70 bool ParseElfHeaders(const EhdrType& ehdr); 71 template <typename EhdrType, typename PhdrType> 72 bool ParseProgramHeaders(const EhdrType& ehdr); 73 template <typename EhdrType, typename ShdrType> 74 bool ExtractSectionHeadersInfo(const EhdrType& ehdr, ShdrType& shdr); 75 template <typename EhdrType, typename ShdrType> 76 bool ParseSectionHeaders(const EhdrType& ehdr); 77 template <typename SymType> 78 bool IsFunc(const SymType sym); 79 template <typename SymType> 80 bool ParseElfSymbols(bool isFunc); 81 template <typename SymType> 82 bool ParseElfSymbols(ElfShdr shdr, bool isFunc); 83 template <typename SymType> 84 bool ParseElfSymbolName(ShdrInfo linkShdr, SymType sym, std::string& nameStr); 85 template <typename SymType> 86 bool ParseElfSymbolByAddr(uint64_t addr, ElfSymbol& elfSymbol); 87 template <typename DynType> 88 bool ParseElfDynamic(); 89 template <typename DynType> 90 bool ParseElfName(); 91 bool ParseStrTab(std::string& nameStr, const uint64_t offset, const uint64_t size); 92 bool GetSectionNameByIndex(std::string& nameStr, const uint32_t name); 93 template <typename SymType> 94 bool ReadSymType(const ElfShdr& shdr, const uint32_t idx, SymType& sym); 95 96 protected: 97 std::vector<ElfSymbol> elfSymbols_; 98 uint64_t dynamicOffset_ = 0; 99 uintptr_t dtPltGotAddr_ = 0; 100 uintptr_t dtStrtabAddr_ = 0; 101 uintptr_t dtStrtabSize_ = 0; 102 uintptr_t dtSonameOffset_ = 0; 103 std::string soname_ = ""; 104 std::shared_ptr<MiniDebugInfo> minidebugInfo_ = nullptr; 105 106 private: 107 std::shared_ptr<DfxMmap> mmap_; 108 ArchType archType_ = ARCH_UNKNOWN; 109 uint64_t elfSize_ = 0; 110 int64_t loadBias_ = 0; 111 uint64_t startVaddr_ = static_cast<uint64_t>(-1); 112 uint64_t startOffset_ = 0; 113 uint64_t endVaddr_ = 0; 114 std::vector<ElfShdr> symShdrs_; 115 std::map<std::pair<uint32_t, const std::string>, ShdrInfo> shdrInfoPairs_; 116 std::unordered_map<uint64_t, ElfLoadInfo> ptLoads_; 117 std::string sectionNames_; 118 }; 119 120 class ElfParser32 : public ElfParser { 121 public: ElfParser32(const std::shared_ptr<DfxMmap> & mmap)122 ElfParser32(const std::shared_ptr<DfxMmap>& mmap) : ElfParser(mmap) {} 123 virtual ~ElfParser32() = default; 124 bool InitHeaders() override; 125 std::string GetElfName() override; 126 uintptr_t GetGlobalPointer() override; 127 const std::vector<ElfSymbol>& GetElfSymbols(bool isFunc) override; 128 bool GetElfSymbolByAddr(uint64_t addr, ElfSymbol& elfSymbol) override; 129 }; 130 131 class ElfParser64 : public ElfParser { 132 public: ElfParser64(const std::shared_ptr<DfxMmap> & mmap)133 ElfParser64(const std::shared_ptr<DfxMmap>& mmap) : ElfParser(mmap) {} 134 virtual ~ElfParser64() = default; 135 bool InitHeaders() override; 136 std::string GetElfName() override; 137 uintptr_t GetGlobalPointer() override; 138 const std::vector<ElfSymbol>& GetElfSymbols(bool isFunc) override; 139 bool GetElfSymbolByAddr(uint64_t addr, ElfSymbol& elfSymbol) override; 140 }; 141 142 } // namespace HiviewDFX 143 } // namespace OHOS 144 #endif 145