• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 ECMASCRIPT_COMPILER_AOT_FILE_ELF_BUILDER_H
17 #define ECMASCRIPT_COMPILER_AOT_FILE_ELF_BUILDER_H
18 
19 #include <map>
20 #include <set>
21 #include <utility>
22 #include <stdint.h>
23 #include <string>
24 #include "ecmascript/compiler/aot_file/aot_file_manager.h"
25 #include "ecmascript/compiler/binary_section.h"
26 
27 namespace panda::ecmascript {
28 
29 class ModuleSectionDes;
30 
31 class ElfBuilder {
32 public:
33     ElfBuilder(const std::vector<ModuleSectionDes> &des,
34                const std::vector<ElfSecName> &sections,
35                bool enableOptDirectCall, Triple triple);
36     ~ElfBuilder();
37     static constexpr uint32_t FuncEntryModuleDesIndex = 0;
38     void PackELFHeader(llvm::ELF::Elf64_Ehdr &header, uint32_t version, Triple triple);
39     void PackELFSections(std::fstream &elfFile);
40     void PackELFSegment(std::fstream &elfFile);
41     void MergeTextSections(std::fstream &elfFile,
42         std::vector<ModuleSectionDes::ModuleRegionInfo> &moduleInfo, llvm::ELF::Elf64_Off &curSecOffset);
43     void MergeArkStackMapSections(std::fstream &elfFile,
44         std::vector<ModuleSectionDes::ModuleRegionInfo> &moduleInfo, llvm::ELF::Elf64_Off &curSecOffset);
45     void MergeStrtabSections(std::fstream &elfFile,
46         std::vector<ModuleSectionDes::ModuleRegionInfo> &moduleInfo, llvm::ELF::Elf64_Off &curSecOffset);
47     void MergeSymtabSections(std::fstream &elfFile, std::vector<ModuleSectionDes::ModuleRegionInfo> &moduleInfo,
48         llvm::ELF::Elf64_Off &curSecOffset, llvm::ELF::Elf64_Off &asmStubOffset);
49     uint32_t AddAsmStubStrTab(std::fstream &elfFile,
50         const std::vector<std::pair<std::string, uint32_t>> &asmStubELFInfo);
51     static llvm::ELF::Elf64_Word FindShName(std::string name, uintptr_t strTabPtr, int strTabSize);
GetFullSecInfo()52     std::map<ElfSecName, std::pair<uint64_t, uint32_t>> GetFullSecInfo() const
53     {
54         return des_[FullSecIndex].GetSectionsInfo();
55     }
SetEnableSecDump(bool flag)56     void SetEnableSecDump(bool flag)
57     {
58         enableSecDump_ = flag;
59     }
60     size_t CalculateTotalFileSize();
61 
62 private:
63     uint32_t GetShIndex(ElfSecName section) const;
64     size_t GetSegmentNum() const;
65     int GetSecNum() const;
66     unsigned GetPFlag(ElfSecName segment) const;
67     ElfSecName GetSegmentName(const ElfSecName &secName) const;
68     std::pair<uint64_t, uint32_t> FindShStrTab() const;
69     void AllocateShdr(std::unique_ptr<llvm::ELF::Elf64_Shdr []> &shdr, const uint32_t &secNum);
70     llvm::ELF::Elf64_Off ComputeEndAddrOfShdr(const uint32_t &secNum) const;
71     bool SupportELF();
72     void DumpSection() const;
73     void AddShStrTabSection();
74     void Initialize();
75     void SetLastSection();
76     void RemoveNotNeedSection();
77     void FixSymtab(llvm::ELF::Elf64_Shdr *shdr, llvm::ELF::Elf64_Off asmStubOffset);
78     void FixUndefinedSymbols(const std::map<std::string_view, llvm::ELF::Elf64_Sym*> &nameToSym,
79                              const std::map<std::string_view, std::vector<llvm::ELF::Elf64_Sym*>> &undefSyms,
80                              llvm::ELF::Elf64_Off asmStubOffset);
81     void CollectUndefSyms(std::map<std::string_view, llvm::ELF::Elf64_Sym *> &nameToSym,
82                           std::map<std::string_view, std::vector<llvm::ELF::Elf64_Sym *>> &undefSyms,
83                           llvm::ELF::Elf64_Sym *sy, std::string_view symName);
84     void ResolveRelocate(std::fstream &elfFile);
85     void ResolveAArch64Relocate(std::fstream &elfFile, Span<llvm::ELF::Elf64_Rela> relas,
86                             Span<llvm::ELF::Elf64_Sym> syms, uint32_t textOff);
87     void ResolveAmd64Relocate(std::fstream &elfFile, Span<llvm::ELF::Elf64_Rela> relas,
88                             Span<llvm::ELF::Elf64_Sym> syms, uint32_t textOff);
89     void CalculateTextSectionSize(llvm::ELF::Elf64_Off &curOffset);
90     void CalculateStrTabSectionSize(llvm::ELF::Elf64_Off &curOffset);
91     void CalculateSymTabSectionSize(llvm::ELF::Elf64_Off &curOffset);
92 
93     static constexpr uint32_t ASMSTUB_MODULE_NUM = 4;
94     static constexpr uint32_t ShStrTableModuleDesIndex = 0;
95     static constexpr uint32_t FullSecIndex = 0;
96     static constexpr int32_t IMM28_MIN = -(1l<<27);
97     static constexpr int32_t IMM28_MAX = 1l<<27;
98     static constexpr uint32_t DIV4_BITS = 2;
99 
100     std::vector<ModuleSectionDes> des_ {};
101     std::unique_ptr<char []> shStrTabPtr_ {nullptr};
102     std::map<ElfSecName, llvm::ELF::Elf64_Shdr> sectionToShdr_;
103     std::map<ElfSecName, llvm::ELF::Elf64_Xword> sectionToAlign_;
104     std::map<ElfSecName, ElfSecName> sectionToSegment_;
105     std::map<ElfSecName, uintptr_t> sectionToFileOffset_;
106     std::map<ElfSecName, unsigned> segmentToFlag_;
107     std::vector<ElfSecName> sections_ {};
108     std::set<ElfSecName> segments_;
109     std::vector<uint32_t> stubTextOffset_ {};
110     std::vector<uint32_t> asmStubStrName_ {};
111     bool enableSecDump_ {false};
112     bool enableOptDirectCall_ {false};
113     Triple triple_;
114     ElfSecName lastDataSection {ElfSecName::NONE};
115     ElfSecName lastCodeSection {ElfSecName::NONE};
116 };
117 }  // namespace panda::ecmascript
118 #endif  // ECMASCRIPT_COMPILER_AOT_FILE_ELF_BUILDER_H
119