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 ParseSectionHeaders(const EhdrType& ehdr); 75 template <typename SymType> 76 bool IsFunc(const SymType sym); 77 template <typename SymType> 78 bool ParseElfSymbols(bool isFunc); 79 template <typename SymType> 80 bool ParseElfSymbols(ElfShdr shdr, bool isFunc); 81 template <typename SymType> 82 bool ParseElfSymbolName(ShdrInfo linkShdr, SymType sym, std::string& nameStr); 83 template <typename SymType> 84 bool ParseElfSymbolByAddr(uint64_t addr, ElfSymbol& elfSymbol); 85 template <typename DynType> 86 bool ParseElfDynamic(); 87 template <typename DynType> 88 bool ParseElfName(); 89 bool ParseStrTab(std::string& nameStr, const uint64_t offset, const uint64_t size); 90 bool GetSectionNameByIndex(std::string& nameStr, const uint32_t name); 91 92 protected: 93 std::vector<ElfSymbol> elfSymbols_; 94 uint64_t dynamicOffset_ = 0; 95 uintptr_t dtPltGotAddr_ = 0; 96 uintptr_t dtStrtabAddr_ = 0; 97 uintptr_t dtStrtabSize_ = 0; 98 uintptr_t dtSonameOffset_ = 0; 99 std::string soname_ = ""; 100 std::shared_ptr<MiniDebugInfo> minidebugInfo_ = nullptr; 101 102 private: 103 std::shared_ptr<DfxMmap> mmap_; 104 ArchType archType_ = ARCH_UNKNOWN; 105 uint64_t elfSize_ = 0; 106 int64_t loadBias_ = 0; 107 uint64_t startVaddr_ = static_cast<uint64_t>(-1); 108 uint64_t startOffset_ = 0; 109 uint64_t endVaddr_ = 0; 110 std::vector<ElfShdr> symShdrs_; 111 std::map<std::pair<uint32_t, const std::string>, ShdrInfo> shdrInfoPairs_; 112 std::unordered_map<uint64_t, ElfLoadInfo> ptLoads_; 113 std::string sectionNames_; 114 }; 115 116 class ElfParser32 : public ElfParser { 117 public: ElfParser32(const std::shared_ptr<DfxMmap> & mmap)118 ElfParser32(const std::shared_ptr<DfxMmap>& mmap) : ElfParser(mmap) {} 119 virtual ~ElfParser32() = default; 120 bool InitHeaders() override; 121 std::string GetElfName() override; 122 uintptr_t GetGlobalPointer() override; 123 const std::vector<ElfSymbol>& GetElfSymbols(bool isFunc) override; 124 bool GetElfSymbolByAddr(uint64_t addr, ElfSymbol& elfSymbol) override; 125 }; 126 127 class ElfParser64 : public ElfParser { 128 public: ElfParser64(const std::shared_ptr<DfxMmap> & mmap)129 ElfParser64(const std::shared_ptr<DfxMmap>& mmap) : ElfParser(mmap) {} 130 virtual ~ElfParser64() = default; 131 bool InitHeaders() override; 132 std::string GetElfName() override; 133 uintptr_t GetGlobalPointer() override; 134 const std::vector<ElfSymbol>& GetElfSymbols(bool isFunc) override; 135 bool GetElfSymbolByAddr(uint64_t addr, ElfSymbol& elfSymbol) override; 136 }; 137 138 } // namespace HiviewDFX 139 } // namespace OHOS 140 #endif 141