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 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 #if is_ohos 44 static size_t GetElfSize(const void* ptr); 45 #endif 46 47 bool IsValid(); 48 uint8_t GetClassType(); 49 ArchType GetArchType(); 50 uint64_t GetElfSize(); 51 std::string GetElfName(); 52 std::string GetBuildId(); 53 void SetBuildId(const std::string& buildId); 54 static std::string GetBuildId(uint64_t noteAddr, uint64_t noteSize); 55 uintptr_t GetGlobalPointer(); 56 int64_t GetLoadBias(); 57 uint64_t GetLoadBase(uint64_t mapStart, uint64_t mapOffset); 58 void SetLoadBase(uint64_t base); 59 uint64_t GetStartPc(); 60 uint64_t GetEndPc(); 61 uint64_t GetStartVaddr(); 62 uint64_t GetEndVaddr(); 63 void SetBaseOffset(uint64_t offset); 64 uint64_t GetBaseOffset(); 65 uint64_t GetStartOffset(); 66 uint64_t GetRelPc(uint64_t pc, uint64_t mapStart, uint64_t mapOffset); 67 const uint8_t* GetMmapPtr(); 68 size_t GetMmapSize(); 69 bool Read(uintptr_t pos, void *buf, size_t size); 70 const std::unordered_map<uint64_t, ElfLoadInfo>& GetPtLoads(); 71 const std::vector<ElfSymbol>& GetElfSymbols(); 72 const std::vector<ElfSymbol>& GetFuncSymbols(); 73 bool GetFuncInfo(uint64_t addr, ElfSymbol& elfSymbol); 74 bool GetFuncInfoLazily(uint64_t addr, ElfSymbol& elfSymbol); 75 bool GetSectionInfo(ShdrInfo& shdr, const std::string secName); 76 bool GetSectionData(unsigned char *buf, uint64_t size, std::string secName); 77 int FindUnwindTableInfo(uintptr_t pc, std::shared_ptr<DfxMap> map, struct UnwindTableInfo& uti); 78 static int FindUnwindTableLocal(uintptr_t pc, struct UnwindTableInfo& uti); 79 static std::string ToReadableBuildId(const std::string& buildIdHex); 80 bool IsEmbeddedElfValid(); 81 std::shared_ptr<DfxElf> GetEmbeddedElf(); 82 std::shared_ptr<MiniDebugInfo> GetMiniDebugInfo(); 83 84 protected: 85 void Init(); 86 void Clear(); 87 bool InitHeaders(); 88 bool InitEmbeddedElf(); 89 #if is_ohos && !is_mingw 90 static int DlPhdrCb(struct dl_phdr_info *info, size_t size, void *data); 91 static bool FindSection(struct dl_phdr_info *info, const std::string secName, ShdrInfo& shdr); 92 static bool FillUnwindTableByEhhdrLocal(struct DwarfEhFrameHdr* hdr, struct UnwindTableInfo* uti); 93 #endif 94 bool FillUnwindTableByEhhdr(struct DwarfEhFrameHdr* hdr, uintptr_t shdrBase, struct UnwindTableInfo* uti); 95 static bool FillUnwindTableByExidx(ShdrInfo shdr, uintptr_t loadBase, struct UnwindTableInfo* uti); 96 bool FindFuncSymbol(uint64_t addr, const std::vector<ElfSymbol>& symbols, ElfSymbol& elfSymbol); 97 98 private: 99 bool valid_ = false; 100 uint8_t classType_ = 0; 101 int64_t loadBias_ = 0; 102 uint64_t loadBase_ = static_cast<uint64_t>(-1); 103 uint64_t startPc_ = static_cast<uint64_t>(-1); 104 uint64_t endPc_ = 0; 105 uint64_t baseOffset_ = 0; // use for so in hap 106 std::string buildId_ = ""; 107 struct UnwindTableInfo uti_; 108 bool hasTableInfo_ = false; 109 std::shared_ptr<DfxMmap> mmap_ = nullptr; 110 std::unique_ptr<ElfParser> elfParse_ = nullptr; 111 std::vector<ElfSymbol> elfSymbols_ {}; 112 std::vector<ElfSymbol> funcSymbols_ {}; 113 std::shared_ptr<DfxElf> embeddedElf_ = nullptr; 114 std::shared_ptr<MiniDebugInfo> miniDebugInfo_ = nullptr; 115 std::shared_ptr<std::vector<uint8_t>> embeddedElfData_ = nullptr; 116 }; 117 } // namespace HiviewDFX 118 } // namespace OHOS 119 #endif 120