1 /* 2 * Copyright (c) 2023-2024 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 16 #ifndef DFX_ELF_H 17 #define DFX_ELF_H 18 19 #include <functional> 20 #include <memory> 21 #include <mutex> 22 #include <set> 23 #include "dfx_elf_parser.h" 24 #include "dfx_map.h" 25 26 namespace OHOS { 27 namespace HiviewDFX { 28 struct DlCbData { 29 uintptr_t pc; 30 UnwindTableInfo uti; 31 bool singleFde = false; 32 }; 33 34 class DfxElf final { 35 public: DfxElf()36 DfxElf() { Init(); } DfxElf(const std::shared_ptr<DfxMmap> & mmap)37 explicit DfxElf (const std::shared_ptr<DfxMmap>& mmap) : mmap_(mmap) { Init(); } ~DfxElf()38 ~DfxElf() { Clear(); } 39 SetMmap(const std::shared_ptr<DfxMmap> & mmap)40 void SetMmap(const std::shared_ptr<DfxMmap>& mmap) { mmap_ = mmap; } 41 bool IsValid(); 42 uint8_t GetClassType(); 43 ArchType GetArchType(); 44 uint64_t GetElfSize(); 45 std::string GetElfName(); 46 std::string GetBuildId(); 47 void SetBuildId(const std::string& buildId); 48 static std::string GetBuildId(uint64_t noteAddr, uint64_t noteSize); 49 GnuDebugDataHdr GetGnuDebugDataHdr(); 50 uintptr_t GetGlobalPointer(); 51 int64_t GetLoadBias(); 52 uint64_t GetLoadBase(uint64_t mapStart, uint64_t mapOffset); 53 void SetLoadBase(uint64_t base); 54 uint64_t GetStartPc(); 55 uint64_t GetEndPc(); 56 uint64_t GetStartVaddr(); 57 uint64_t GetEndVaddr(); 58 void SetBaseOffset(uint64_t offset); 59 uint64_t GetBaseOffset(); 60 uint64_t GetStartOffset(); 61 uint64_t GetRelPc(uint64_t pc, uint64_t mapStart, uint64_t mapOffset); 62 const uint8_t* GetMmapPtr(); 63 size_t GetMmapSize(); 64 bool Read(uintptr_t pos, void* buf, size_t size); 65 const std::unordered_map<uint64_t, ElfLoadInfo>& GetPtLoads(); 66 const std::set<ElfSymbol>& GetFuncSymbols(); 67 bool GetFuncInfo(uint64_t addr, ElfSymbol& elfSymbol); 68 bool GetSectionInfo(ShdrInfo& shdr, const std::string secName); 69 bool GetSectionData(unsigned char* buf, uint64_t size, std::string secName); 70 int FindUnwindTableInfo(uintptr_t pc, std::shared_ptr<DfxMap> map, struct UnwindTableInfo& uti); 71 static int FindUnwindTableLocal(uintptr_t pc, struct UnwindTableInfo& uti); 72 73 protected: 74 void Init(); 75 void Clear(); 76 bool InitHeaders(); 77 bool IsMiniDebugInfoValid(); 78 #if is_ohos && !is_mingw 79 static int DlPhdrCb(struct dl_phdr_info* info, size_t size, void* data); 80 static void ParsePhdr(struct dl_phdr_info* info, const ElfW(Phdr)* (&pHdrSections)[4], const uintptr_t pc); 81 static bool ProccessDynamic(const ElfW(Phdr)* pDynamic, ElfW(Addr) loadBase, UnwindTableInfo* uti); 82 static struct DwarfEhFrameHdr* InitHdr(struct DwarfEhFrameHdr& synthHdr, 83 struct dl_phdr_info* info, const ElfW(Phdr)* pEhHdr); 84 static bool FindSection(struct dl_phdr_info* info, const std::string secName, ShdrInfo& shdr); 85 static bool FillUnwindTableByEhhdrLocal(struct DwarfEhFrameHdr* hdr, struct UnwindTableInfo* uti); 86 #endif 87 bool FillUnwindTableByEhhdr(struct DwarfEhFrameHdr* hdr, uintptr_t shdrBase, struct UnwindTableInfo* uti); 88 static bool FillUnwindTableByExidx(ShdrInfo shdr, uintptr_t loadBase, struct UnwindTableInfo* uti); 89 bool FindFuncSymbol(uint64_t addr, const std::set<ElfSymbol>& symbols, ElfSymbol& elfSymbol); 90 bool IsValidElf(const void* ptr, size_t size); 91 bool GetFuncInfoLazily(uint64_t addr, ElfSymbol& elfSymbol); 92 93 private: 94 bool valid_ = false; 95 uint8_t classType_ = 0; 96 int64_t loadBias_ = 0; 97 uint64_t loadBase_ = static_cast<uint64_t>(-1); 98 uint64_t startPc_ = static_cast<uint64_t>(-1); 99 uint64_t endPc_ = 0; 100 uint64_t baseOffset_ = 0; // use for so in hap 101 std::string buildId_ = ""; 102 struct UnwindTableInfo uti_; 103 bool hasTableInfo_ = false; 104 std::shared_ptr<DfxMmap> mmap_ = nullptr; 105 std::unique_ptr<ElfParser> elfParse_ = nullptr; 106 std::set<ElfSymbol> funcSymbols_ {}; 107 std::shared_ptr<DfxElf> miniDebugInfo_ = nullptr; 108 }; 109 } // namespace HiviewDFX 110 } // namespace OHOS 111 #endif 112