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