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