1800b99b8Sopenharmony_ci/* 2800b99b8Sopenharmony_ci * Copyright (c) 2023-2024 Huawei Device Co., Ltd. 3800b99b8Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 4800b99b8Sopenharmony_ci * you may not use this file except in compliance with the License. 5800b99b8Sopenharmony_ci * You may obtain a copy of the License at 6800b99b8Sopenharmony_ci * 7800b99b8Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 8800b99b8Sopenharmony_ci * 9800b99b8Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 10800b99b8Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 11800b99b8Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12800b99b8Sopenharmony_ci * See the License for the specific language governing permissions and 13800b99b8Sopenharmony_ci * limitations under the License. 14800b99b8Sopenharmony_ci */ 15800b99b8Sopenharmony_ci 16800b99b8Sopenharmony_ci#ifndef DFX_ELF_H 17800b99b8Sopenharmony_ci#define DFX_ELF_H 18800b99b8Sopenharmony_ci 19800b99b8Sopenharmony_ci#include <memory> 20800b99b8Sopenharmony_ci#include <mutex> 21800b99b8Sopenharmony_ci#include "dfx_elf_parser.h" 22800b99b8Sopenharmony_ci#include "dfx_map.h" 23800b99b8Sopenharmony_ci 24800b99b8Sopenharmony_cinamespace OHOS { 25800b99b8Sopenharmony_cinamespace HiviewDFX { 26800b99b8Sopenharmony_cistruct DlCbData { 27800b99b8Sopenharmony_ci uintptr_t pc; 28800b99b8Sopenharmony_ci UnwindTableInfo uti; 29800b99b8Sopenharmony_ci bool singleFde = false; 30800b99b8Sopenharmony_ci}; 31800b99b8Sopenharmony_ci 32800b99b8Sopenharmony_ciclass DfxElf final { 33800b99b8Sopenharmony_cipublic: 34800b99b8Sopenharmony_ci static std::shared_ptr<DfxElf> Create(const std::string& file); 35800b99b8Sopenharmony_ci static std::shared_ptr<DfxElf> CreateFromHap(const std::string& file, std::shared_ptr<DfxMap> prevMap, 36800b99b8Sopenharmony_ci uint64_t& offset); 37800b99b8Sopenharmony_ci explicit DfxElf(const std::string& file); 38800b99b8Sopenharmony_ci explicit DfxElf(const int fd, const size_t elfSz, const off_t offset); 39800b99b8Sopenharmony_ci DfxElf(uint8_t *decompressedData, size_t size); 40800b99b8Sopenharmony_ci ~DfxElf() { Clear(); } 41800b99b8Sopenharmony_ci 42800b99b8Sopenharmony_ci static bool IsValidElf(const void* ptr, size_t size); 43800b99b8Sopenharmony_ci static size_t GetElfSize(const void* ptr); 44800b99b8Sopenharmony_ci 45800b99b8Sopenharmony_ci bool IsValid(); 46800b99b8Sopenharmony_ci uint8_t GetClassType(); 47800b99b8Sopenharmony_ci ArchType GetArchType(); 48800b99b8Sopenharmony_ci uint64_t GetElfSize(); 49800b99b8Sopenharmony_ci std::string GetElfName(); 50800b99b8Sopenharmony_ci std::string GetBuildId(); 51800b99b8Sopenharmony_ci void SetBuildId(const std::string& buildId); 52800b99b8Sopenharmony_ci static std::string GetBuildId(uint64_t noteAddr, uint64_t noteSize); 53800b99b8Sopenharmony_ci uintptr_t GetGlobalPointer(); 54800b99b8Sopenharmony_ci int64_t GetLoadBias(); 55800b99b8Sopenharmony_ci uint64_t GetLoadBase(uint64_t mapStart, uint64_t mapOffset); 56800b99b8Sopenharmony_ci void SetLoadBase(uint64_t base); 57800b99b8Sopenharmony_ci uint64_t GetStartPc(); 58800b99b8Sopenharmony_ci uint64_t GetEndPc(); 59800b99b8Sopenharmony_ci uint64_t GetStartVaddr(); 60800b99b8Sopenharmony_ci uint64_t GetEndVaddr(); 61800b99b8Sopenharmony_ci void SetBaseOffset(uint64_t offset); 62800b99b8Sopenharmony_ci uint64_t GetBaseOffset(); 63800b99b8Sopenharmony_ci uint64_t GetStartOffset(); 64800b99b8Sopenharmony_ci uint64_t GetRelPc(uint64_t pc, uint64_t mapStart, uint64_t mapOffset); 65800b99b8Sopenharmony_ci const uint8_t* GetMmapPtr(); 66800b99b8Sopenharmony_ci size_t GetMmapSize(); 67800b99b8Sopenharmony_ci bool Read(uintptr_t pos, void *buf, size_t size); 68800b99b8Sopenharmony_ci const std::unordered_map<uint64_t, ElfLoadInfo>& GetPtLoads(); 69800b99b8Sopenharmony_ci const std::vector<ElfSymbol>& GetElfSymbols(); 70800b99b8Sopenharmony_ci const std::vector<ElfSymbol>& GetFuncSymbols(); 71800b99b8Sopenharmony_ci bool GetFuncInfo(uint64_t addr, ElfSymbol& elfSymbol); 72800b99b8Sopenharmony_ci bool GetFuncInfoLazily(uint64_t addr, ElfSymbol& elfSymbol); 73800b99b8Sopenharmony_ci bool GetSectionInfo(ShdrInfo& shdr, const std::string secName); 74800b99b8Sopenharmony_ci bool GetSectionData(unsigned char *buf, uint64_t size, std::string secName); 75800b99b8Sopenharmony_ci int FindUnwindTableInfo(uintptr_t pc, std::shared_ptr<DfxMap> map, struct UnwindTableInfo& uti); 76800b99b8Sopenharmony_ci static int FindUnwindTableLocal(uintptr_t pc, struct UnwindTableInfo& uti); 77800b99b8Sopenharmony_ci static std::string ToReadableBuildId(const std::string& buildIdHex); 78800b99b8Sopenharmony_ci bool IsEmbeddedElfValid(); 79800b99b8Sopenharmony_ci std::shared_ptr<DfxElf> GetEmbeddedElf(); 80800b99b8Sopenharmony_ci std::shared_ptr<MiniDebugInfo> GetMiniDebugInfo(); 81800b99b8Sopenharmony_ci 82800b99b8Sopenharmony_ciprotected: 83800b99b8Sopenharmony_ci void Init(); 84800b99b8Sopenharmony_ci void Clear(); 85800b99b8Sopenharmony_ci bool InitHeaders(); 86800b99b8Sopenharmony_ci bool InitEmbeddedElf(); 87800b99b8Sopenharmony_ci#if is_ohos && !is_mingw 88800b99b8Sopenharmony_ci static int DlPhdrCb(struct dl_phdr_info *info, size_t size, void *data); 89800b99b8Sopenharmony_ci static bool FindSection(struct dl_phdr_info *info, const std::string secName, ShdrInfo& shdr); 90800b99b8Sopenharmony_ci static bool FillUnwindTableByEhhdrLocal(struct DwarfEhFrameHdr* hdr, struct UnwindTableInfo* uti); 91800b99b8Sopenharmony_ci#endif 92800b99b8Sopenharmony_ci bool FillUnwindTableByEhhdr(struct DwarfEhFrameHdr* hdr, uintptr_t shdrBase, struct UnwindTableInfo* uti); 93800b99b8Sopenharmony_ci static bool FillUnwindTableByExidx(ShdrInfo shdr, uintptr_t loadBase, struct UnwindTableInfo* uti); 94800b99b8Sopenharmony_ci bool FindFuncSymbol(uint64_t addr, const std::vector<ElfSymbol>& symbols, ElfSymbol& elfSymbol); 95800b99b8Sopenharmony_ci 96800b99b8Sopenharmony_ciprivate: 97800b99b8Sopenharmony_ci bool valid_ = false; 98800b99b8Sopenharmony_ci uint8_t classType_ = 0; 99800b99b8Sopenharmony_ci int64_t loadBias_ = 0; 100800b99b8Sopenharmony_ci uint64_t loadBase_ = static_cast<uint64_t>(-1); 101800b99b8Sopenharmony_ci uint64_t startPc_ = static_cast<uint64_t>(-1); 102800b99b8Sopenharmony_ci uint64_t endPc_ = 0; 103800b99b8Sopenharmony_ci uint64_t baseOffset_ = 0; // use for so in hap 104800b99b8Sopenharmony_ci std::string buildId_ = ""; 105800b99b8Sopenharmony_ci struct UnwindTableInfo uti_; 106800b99b8Sopenharmony_ci bool hasTableInfo_ = false; 107800b99b8Sopenharmony_ci std::shared_ptr<DfxMmap> mmap_ = nullptr; 108800b99b8Sopenharmony_ci std::unique_ptr<ElfParser> elfParse_ = nullptr; 109800b99b8Sopenharmony_ci std::vector<ElfSymbol> elfSymbols_ {}; 110800b99b8Sopenharmony_ci std::vector<ElfSymbol> funcSymbols_ {}; 111800b99b8Sopenharmony_ci std::shared_ptr<DfxElf> embeddedElf_ = nullptr; 112800b99b8Sopenharmony_ci std::shared_ptr<MiniDebugInfo> miniDebugInfo_ = nullptr; 113800b99b8Sopenharmony_ci std::shared_ptr<std::vector<uint8_t>> embeddedElfData_ = nullptr; 114800b99b8Sopenharmony_ci}; 115800b99b8Sopenharmony_ci} // namespace HiviewDFX 116800b99b8Sopenharmony_ci} // namespace OHOS 117800b99b8Sopenharmony_ci#endif 118