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> §ions, 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