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
41namespace OHOS {
42namespace HiviewDFX {
43class ElfParser {
44public:
45    ElfParser(const std::shared_ptr<DfxMmap>& mmap) : mmap_(mmap) {}
46    virtual ~ElfParser() = default;
47
48    virtual bool InitHeaders() = 0;
49    virtual ArchType GetArchType() { return archType_; }
50    virtual uint64_t GetElfSize();
51    virtual int64_t GetLoadBias() { return loadBias_; }
52    virtual uint64_t GetStartVaddr() { return startVaddr_; }
53    virtual uint64_t GetEndVaddr() { return endVaddr_; }
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;
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();
65protected:
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
92protected:
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
102private:
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
116class ElfParser32 : public ElfParser {
117public:
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
127class ElfParser64 : public ElfParser {
128public:
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