1800b99b8Sopenharmony_ci/*
2800b99b8Sopenharmony_ci * Copyright (c) 2023 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#ifndef DFX_ELF_PARSER_H
16800b99b8Sopenharmony_ci#define DFX_ELF_PARSER_H
17800b99b8Sopenharmony_ci
18800b99b8Sopenharmony_ci#include <cstddef>
19800b99b8Sopenharmony_ci#if is_mingw
20800b99b8Sopenharmony_ci#include "dfx_nonlinux_define.h"
21800b99b8Sopenharmony_ci#else
22800b99b8Sopenharmony_ci#include <elf.h>
23800b99b8Sopenharmony_ci#include <link.h>
24800b99b8Sopenharmony_ci#endif
25800b99b8Sopenharmony_ci#include <map>
26800b99b8Sopenharmony_ci#include <memory>
27800b99b8Sopenharmony_ci#include <stdint.h>
28800b99b8Sopenharmony_ci#include <string>
29800b99b8Sopenharmony_ci#include <sys/stat.h>
30800b99b8Sopenharmony_ci#include <sys/types.h>
31800b99b8Sopenharmony_ci#include <unistd.h>
32800b99b8Sopenharmony_ci#include <unordered_map>
33800b99b8Sopenharmony_ci#include <vector>
34800b99b8Sopenharmony_ci
35800b99b8Sopenharmony_ci#include "dfx_define.h"
36800b99b8Sopenharmony_ci#include "dfx_elf_define.h"
37800b99b8Sopenharmony_ci#include "dfx_mmap.h"
38800b99b8Sopenharmony_ci#include "dfx_symbol.h"
39800b99b8Sopenharmony_ci#include "unwind_context.h"
40800b99b8Sopenharmony_ci
41800b99b8Sopenharmony_cinamespace OHOS {
42800b99b8Sopenharmony_cinamespace HiviewDFX {
43800b99b8Sopenharmony_ciclass ElfParser {
44800b99b8Sopenharmony_cipublic:
45800b99b8Sopenharmony_ci    ElfParser(const std::shared_ptr<DfxMmap>& mmap) : mmap_(mmap) {}
46800b99b8Sopenharmony_ci    virtual ~ElfParser() = default;
47800b99b8Sopenharmony_ci
48800b99b8Sopenharmony_ci    virtual bool InitHeaders() = 0;
49800b99b8Sopenharmony_ci    virtual ArchType GetArchType() { return archType_; }
50800b99b8Sopenharmony_ci    virtual uint64_t GetElfSize();
51800b99b8Sopenharmony_ci    virtual int64_t GetLoadBias() { return loadBias_; }
52800b99b8Sopenharmony_ci    virtual uint64_t GetStartVaddr() { return startVaddr_; }
53800b99b8Sopenharmony_ci    virtual uint64_t GetEndVaddr() { return endVaddr_; }
54800b99b8Sopenharmony_ci    virtual uint64_t GetStartOffset() { return startOffset_; }
55800b99b8Sopenharmony_ci    virtual std::string GetElfName() = 0;
56800b99b8Sopenharmony_ci    virtual uintptr_t GetGlobalPointer() = 0;
57800b99b8Sopenharmony_ci    virtual const std::vector<ElfSymbol>& GetElfSymbols(bool isFunc) = 0;
58800b99b8Sopenharmony_ci    virtual bool GetSectionInfo(ShdrInfo& shdr, const uint32_t idx);
59800b99b8Sopenharmony_ci    virtual bool GetSectionInfo(ShdrInfo& shdr, const std::string& secName);
60800b99b8Sopenharmony_ci    virtual bool GetSectionData(unsigned char *buf, uint64_t size, std::string secName);
61800b99b8Sopenharmony_ci    virtual bool GetElfSymbolByAddr(uint64_t addr, ElfSymbol& elfSymbol) = 0;
62800b99b8Sopenharmony_ci    const std::unordered_map<uint64_t, ElfLoadInfo>& GetPtLoads() {return ptLoads_;}
63800b99b8Sopenharmony_ci    bool Read(uintptr_t pos, void *buf, size_t size);
64800b99b8Sopenharmony_ci    std::shared_ptr<MiniDebugInfo> GetMiniDebugInfo();
65800b99b8Sopenharmony_ciprotected:
66800b99b8Sopenharmony_ci    size_t MmapSize();
67800b99b8Sopenharmony_ci    template <typename EhdrType, typename PhdrType, typename ShdrType>
68800b99b8Sopenharmony_ci    bool ParseAllHeaders();
69800b99b8Sopenharmony_ci    template <typename EhdrType>
70800b99b8Sopenharmony_ci    bool ParseElfHeaders(const EhdrType& ehdr);
71800b99b8Sopenharmony_ci    template <typename EhdrType, typename PhdrType>
72800b99b8Sopenharmony_ci    bool ParseProgramHeaders(const EhdrType& ehdr);
73800b99b8Sopenharmony_ci    template <typename EhdrType, typename ShdrType>
74800b99b8Sopenharmony_ci    bool ParseSectionHeaders(const EhdrType& ehdr);
75800b99b8Sopenharmony_ci    template <typename SymType>
76800b99b8Sopenharmony_ci    bool IsFunc(const SymType sym);
77800b99b8Sopenharmony_ci    template <typename SymType>
78800b99b8Sopenharmony_ci    bool ParseElfSymbols(bool isFunc);
79800b99b8Sopenharmony_ci    template <typename SymType>
80800b99b8Sopenharmony_ci    bool ParseElfSymbols(ElfShdr shdr, bool isFunc);
81800b99b8Sopenharmony_ci    template <typename SymType>
82800b99b8Sopenharmony_ci    bool ParseElfSymbolName(ShdrInfo linkShdr, SymType sym, std::string& nameStr);
83800b99b8Sopenharmony_ci    template <typename SymType>
84800b99b8Sopenharmony_ci    bool ParseElfSymbolByAddr(uint64_t addr, ElfSymbol& elfSymbol);
85800b99b8Sopenharmony_ci    template <typename DynType>
86800b99b8Sopenharmony_ci    bool ParseElfDynamic();
87800b99b8Sopenharmony_ci    template <typename DynType>
88800b99b8Sopenharmony_ci    bool ParseElfName();
89800b99b8Sopenharmony_ci    bool ParseStrTab(std::string& nameStr, const uint64_t offset, const uint64_t size);
90800b99b8Sopenharmony_ci    bool GetSectionNameByIndex(std::string& nameStr, const uint32_t name);
91800b99b8Sopenharmony_ci
92800b99b8Sopenharmony_ciprotected:
93800b99b8Sopenharmony_ci    std::vector<ElfSymbol> elfSymbols_;
94800b99b8Sopenharmony_ci    uint64_t dynamicOffset_ = 0;
95800b99b8Sopenharmony_ci    uintptr_t dtPltGotAddr_ = 0;
96800b99b8Sopenharmony_ci    uintptr_t dtStrtabAddr_ = 0;
97800b99b8Sopenharmony_ci    uintptr_t dtStrtabSize_ = 0;
98800b99b8Sopenharmony_ci    uintptr_t dtSonameOffset_ = 0;
99800b99b8Sopenharmony_ci    std::string soname_ = "";
100800b99b8Sopenharmony_ci    std::shared_ptr<MiniDebugInfo> minidebugInfo_ = nullptr;
101800b99b8Sopenharmony_ci
102800b99b8Sopenharmony_ciprivate:
103800b99b8Sopenharmony_ci    std::shared_ptr<DfxMmap> mmap_;
104800b99b8Sopenharmony_ci    ArchType archType_ = ARCH_UNKNOWN;
105800b99b8Sopenharmony_ci    uint64_t elfSize_ = 0;
106800b99b8Sopenharmony_ci    int64_t loadBias_ = 0;
107800b99b8Sopenharmony_ci    uint64_t startVaddr_ = static_cast<uint64_t>(-1);
108800b99b8Sopenharmony_ci    uint64_t startOffset_ = 0;
109800b99b8Sopenharmony_ci    uint64_t endVaddr_ = 0;
110800b99b8Sopenharmony_ci    std::vector<ElfShdr> symShdrs_;
111800b99b8Sopenharmony_ci    std::map<std::pair<uint32_t, const std::string>, ShdrInfo> shdrInfoPairs_;
112800b99b8Sopenharmony_ci    std::unordered_map<uint64_t, ElfLoadInfo> ptLoads_;
113800b99b8Sopenharmony_ci    std::string sectionNames_;
114800b99b8Sopenharmony_ci};
115800b99b8Sopenharmony_ci
116800b99b8Sopenharmony_ciclass ElfParser32 : public ElfParser {
117800b99b8Sopenharmony_cipublic:
118800b99b8Sopenharmony_ci    ElfParser32(const std::shared_ptr<DfxMmap>& mmap) : ElfParser(mmap) {}
119800b99b8Sopenharmony_ci    virtual ~ElfParser32() = default;
120800b99b8Sopenharmony_ci    bool InitHeaders() override;
121800b99b8Sopenharmony_ci    std::string GetElfName() override;
122800b99b8Sopenharmony_ci    uintptr_t GetGlobalPointer() override;
123800b99b8Sopenharmony_ci    const std::vector<ElfSymbol>& GetElfSymbols(bool isFunc) override;
124800b99b8Sopenharmony_ci    bool GetElfSymbolByAddr(uint64_t addr, ElfSymbol& elfSymbol) override;
125800b99b8Sopenharmony_ci};
126800b99b8Sopenharmony_ci
127800b99b8Sopenharmony_ciclass ElfParser64 : public ElfParser {
128800b99b8Sopenharmony_cipublic:
129800b99b8Sopenharmony_ci    ElfParser64(const std::shared_ptr<DfxMmap>& mmap) : ElfParser(mmap) {}
130800b99b8Sopenharmony_ci    virtual ~ElfParser64() = default;
131800b99b8Sopenharmony_ci    bool InitHeaders() override;
132800b99b8Sopenharmony_ci    std::string GetElfName() override;
133800b99b8Sopenharmony_ci    uintptr_t GetGlobalPointer() override;
134800b99b8Sopenharmony_ci    const std::vector<ElfSymbol>& GetElfSymbols(bool isFunc) override;
135800b99b8Sopenharmony_ci    bool GetElfSymbolByAddr(uint64_t addr, ElfSymbol& elfSymbol) override;
136800b99b8Sopenharmony_ci};
137800b99b8Sopenharmony_ci
138800b99b8Sopenharmony_ci} // namespace HiviewDFX
139800b99b8Sopenharmony_ci} // namespace OHOS
140800b99b8Sopenharmony_ci#endif
141