14514f5e3Sopenharmony_ci/* 24514f5e3Sopenharmony_ci * Copyright (c) 2023 Huawei Device Co., Ltd. 34514f5e3Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 44514f5e3Sopenharmony_ci * you may not use this file except in compliance with the License. 54514f5e3Sopenharmony_ci * You may obtain a copy of the License at 64514f5e3Sopenharmony_ci * 74514f5e3Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 84514f5e3Sopenharmony_ci * 94514f5e3Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 104514f5e3Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 114514f5e3Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 124514f5e3Sopenharmony_ci * See the License for the specific language governing permissions and 134514f5e3Sopenharmony_ci * limitations under the License. 144514f5e3Sopenharmony_ci */ 154514f5e3Sopenharmony_ci 164514f5e3Sopenharmony_ci#include "ecmascript/compiler/aot_file/elf_builder.h" 174514f5e3Sopenharmony_ci 184514f5e3Sopenharmony_cinamespace panda::ecmascript { 194514f5e3Sopenharmony_civoid ElfBuilder::AddShStrTabSection() 204514f5e3Sopenharmony_ci{ 214514f5e3Sopenharmony_ci std::map<ElfSecName, std::pair<uint64_t, uint32_t>> §ions = 224514f5e3Sopenharmony_ci des_[ShStrTableModuleDesIndex].GetSectionsInfo(); 234514f5e3Sopenharmony_ci 244514f5e3Sopenharmony_ci uint32_t size = 1; 254514f5e3Sopenharmony_ci for (auto &s : sections_) { 264514f5e3Sopenharmony_ci std::string str = ModuleSectionDes::GetSecName(s); 274514f5e3Sopenharmony_ci size = size + str.size() + 1; 284514f5e3Sopenharmony_ci } 294514f5e3Sopenharmony_ci 304514f5e3Sopenharmony_ci shStrTabPtr_ = std::make_unique<char []>(size); 314514f5e3Sopenharmony_ci char *dst = shStrTabPtr_.get(); 324514f5e3Sopenharmony_ci dst[0] = 0x0; 334514f5e3Sopenharmony_ci uint32_t i = 1; 344514f5e3Sopenharmony_ci for (auto &s: sections_) { 354514f5e3Sopenharmony_ci std::string str = ModuleSectionDes::GetSecName(s); 364514f5e3Sopenharmony_ci uint32_t copySize = str.size(); 374514f5e3Sopenharmony_ci if (copySize == 0) { 384514f5e3Sopenharmony_ci UNREACHABLE(); 394514f5e3Sopenharmony_ci } 404514f5e3Sopenharmony_ci ASSERT(size >= i); 414514f5e3Sopenharmony_ci if ((copySize != 0) && ((memcpy_s(dst + i, size - i + 1, str.data(), copySize)) != EOK)) { 424514f5e3Sopenharmony_ci UNREACHABLE(); 434514f5e3Sopenharmony_ci } 444514f5e3Sopenharmony_ci dst[i + copySize] = 0x0; 454514f5e3Sopenharmony_ci i = i + copySize + 1; 464514f5e3Sopenharmony_ci } 474514f5e3Sopenharmony_ci if (sections.find(ElfSecName::SHSTRTAB) != sections.end()) { 484514f5e3Sopenharmony_ci sections.erase(ElfSecName::SHSTRTAB); 494514f5e3Sopenharmony_ci } 504514f5e3Sopenharmony_ci sections[ElfSecName::SHSTRTAB] = std::make_pair(reinterpret_cast<uint64_t>(shStrTabPtr_.get()), size); 514514f5e3Sopenharmony_ci if (enableSecDump_) { 524514f5e3Sopenharmony_ci DumpSection(); 534514f5e3Sopenharmony_ci } 544514f5e3Sopenharmony_ci} 554514f5e3Sopenharmony_ci 564514f5e3Sopenharmony_ciuint32_t ElfBuilder::AddAsmStubStrTab(std::ofstream &elfFile, 574514f5e3Sopenharmony_ci const std::vector<std::pair<std::string, uint32_t>> &asmStubELFInfo) 584514f5e3Sopenharmony_ci{ 594514f5e3Sopenharmony_ci uint32_t size = 1; 604514f5e3Sopenharmony_ci ASSERT(asmStubELFInfo.size() > 0); 614514f5e3Sopenharmony_ci uint32_t asmStubSymTabNum = asmStubELFInfo.size() - 1; 624514f5e3Sopenharmony_ci for (size_t idx = 0; idx < asmStubSymTabNum; ++idx) { 634514f5e3Sopenharmony_ci const std::string &str = asmStubELFInfo[idx].first; 644514f5e3Sopenharmony_ci size = size + str.size() + 1; 654514f5e3Sopenharmony_ci } 664514f5e3Sopenharmony_ci 674514f5e3Sopenharmony_ci std::unique_ptr<char []> asmStubStrTabPtr = std::make_unique<char []>(size); 684514f5e3Sopenharmony_ci char *dst = asmStubStrTabPtr.get(); 694514f5e3Sopenharmony_ci dst[0] = 0x0; 704514f5e3Sopenharmony_ci uint32_t i = 1; 714514f5e3Sopenharmony_ci for (size_t idx = 0; idx < asmStubSymTabNum; ++idx) { 724514f5e3Sopenharmony_ci const std::string &str = asmStubELFInfo[idx].first; 734514f5e3Sopenharmony_ci asmStubStrName_.emplace_back(i); 744514f5e3Sopenharmony_ci uint32_t copySize = str.size(); 754514f5e3Sopenharmony_ci if (copySize == 0) { 764514f5e3Sopenharmony_ci UNREACHABLE(); 774514f5e3Sopenharmony_ci } 784514f5e3Sopenharmony_ci if ((copySize != 0) && ((memcpy_s(dst + i, size - i + 1, str.data(), copySize)) != EOK)) { 794514f5e3Sopenharmony_ci UNREACHABLE(); 804514f5e3Sopenharmony_ci } 814514f5e3Sopenharmony_ci dst[i + copySize] = 0x0; 824514f5e3Sopenharmony_ci i = i + copySize + 1; 834514f5e3Sopenharmony_ci } 844514f5e3Sopenharmony_ci elfFile.write(reinterpret_cast<char *>(dst), size); 854514f5e3Sopenharmony_ci return size; 864514f5e3Sopenharmony_ci} 874514f5e3Sopenharmony_ci 884514f5e3Sopenharmony_civoid ElfBuilder::DumpSection() const 894514f5e3Sopenharmony_ci{ 904514f5e3Sopenharmony_ci const std::map<ElfSecName, std::pair<uint64_t, uint32_t>> §ions = GetFullSecInfo(); 914514f5e3Sopenharmony_ci // dump 924514f5e3Sopenharmony_ci for (auto &s : sections) { 934514f5e3Sopenharmony_ci ElfSection section = ElfSection(s.first); 944514f5e3Sopenharmony_ci if (!section.ShouldDumpToAOTFile()) { 954514f5e3Sopenharmony_ci continue; 964514f5e3Sopenharmony_ci } 974514f5e3Sopenharmony_ci LOG_COMPILER(INFO) << "secname :" << std::dec << static_cast<int>(s.first) 984514f5e3Sopenharmony_ci << " addr:0x" << std::hex << s.second.first << " size:0x" << s.second.second << std::endl; 994514f5e3Sopenharmony_ci } 1004514f5e3Sopenharmony_ci} 1014514f5e3Sopenharmony_ci 1024514f5e3Sopenharmony_ciElfBuilder::ElfBuilder(const std::vector<ModuleSectionDes> &des, 1034514f5e3Sopenharmony_ci const std::vector<ElfSecName> §ions): des_(des), sections_(sections) 1044514f5e3Sopenharmony_ci{ 1054514f5e3Sopenharmony_ci Initialize(); 1064514f5e3Sopenharmony_ci AddShStrTabSection(); 1074514f5e3Sopenharmony_ci RemoveNotNeedSection(); 1084514f5e3Sopenharmony_ci} 1094514f5e3Sopenharmony_ci 1104514f5e3Sopenharmony_civoid ElfBuilder::Initialize() 1114514f5e3Sopenharmony_ci{ 1124514f5e3Sopenharmony_ci for (size_t i = 0; i < des_.size(); i++) { 1134514f5e3Sopenharmony_ci des_[i].AddArkStackMapSection(); 1144514f5e3Sopenharmony_ci } 1154514f5e3Sopenharmony_ci sectionToAlign_ = { 1164514f5e3Sopenharmony_ci {ElfSecName::TEXT, AOTFileInfo::PAGE_ALIGN}, 1174514f5e3Sopenharmony_ci {ElfSecName::STRTAB, 1}, 1184514f5e3Sopenharmony_ci {ElfSecName::SYMTAB, AOTFileInfo::DATA_SEC_ALIGN}, 1194514f5e3Sopenharmony_ci {ElfSecName::SHSTRTAB, AOTFileInfo::DATA_SEC_ALIGN}, 1204514f5e3Sopenharmony_ci {ElfSecName::ARK_STACKMAP, AOTFileInfo::DATA_SEC_ALIGN}, 1214514f5e3Sopenharmony_ci {ElfSecName::ARK_FUNCENTRY, AOTFileInfo::DATA_SEC_ALIGN}, 1224514f5e3Sopenharmony_ci {ElfSecName::ARK_ASMSTUB, AOTFileInfo::DATA_SEC_ALIGN}, 1234514f5e3Sopenharmony_ci {ElfSecName::ARK_MODULEINFO, AOTFileInfo::DATA_SEC_ALIGN}, 1244514f5e3Sopenharmony_ci }; 1254514f5e3Sopenharmony_ci 1264514f5e3Sopenharmony_ci sectionToSegment_ = { 1274514f5e3Sopenharmony_ci {ElfSecName::RODATA, ElfSecName::TEXT}, 1284514f5e3Sopenharmony_ci {ElfSecName::RODATA_CST4, ElfSecName::TEXT}, 1294514f5e3Sopenharmony_ci {ElfSecName::RODATA_CST8, ElfSecName::TEXT}, 1304514f5e3Sopenharmony_ci {ElfSecName::RODATA_CST16, ElfSecName::TEXT}, 1314514f5e3Sopenharmony_ci {ElfSecName::RODATA_CST32, ElfSecName::TEXT}, 1324514f5e3Sopenharmony_ci {ElfSecName::TEXT, ElfSecName::TEXT}, 1334514f5e3Sopenharmony_ci {ElfSecName::STRTAB, ElfSecName::DATA}, 1344514f5e3Sopenharmony_ci {ElfSecName::SYMTAB, ElfSecName::DATA}, 1354514f5e3Sopenharmony_ci {ElfSecName::SHSTRTAB, ElfSecName::DATA}, 1364514f5e3Sopenharmony_ci {ElfSecName::ARK_STACKMAP, ElfSecName::DATA}, 1374514f5e3Sopenharmony_ci {ElfSecName::ARK_FUNCENTRY, ElfSecName::DATA}, 1384514f5e3Sopenharmony_ci {ElfSecName::ARK_ASMSTUB, ElfSecName::TEXT}, 1394514f5e3Sopenharmony_ci {ElfSecName::ARK_MODULEINFO, ElfSecName::DATA}, 1404514f5e3Sopenharmony_ci }; 1414514f5e3Sopenharmony_ci 1424514f5e3Sopenharmony_ci segmentToFlag_ = { 1434514f5e3Sopenharmony_ci {ElfSecName::TEXT, llvm::ELF::PF_X | llvm::ELF::PF_R}, 1444514f5e3Sopenharmony_ci {ElfSecName::DATA, llvm::ELF::PF_R}, 1454514f5e3Sopenharmony_ci }; 1464514f5e3Sopenharmony_ci 1474514f5e3Sopenharmony_ci SetLastSection(); 1484514f5e3Sopenharmony_ci} 1494514f5e3Sopenharmony_ci 1504514f5e3Sopenharmony_civoid ElfBuilder::RemoveNotNeedSection() 1514514f5e3Sopenharmony_ci{ 1524514f5e3Sopenharmony_ci const std::map<ElfSecName, std::pair<uint64_t, uint32_t>> §ions = GetFullSecInfo(); 1534514f5e3Sopenharmony_ci for (size_t i = 0; i < sections_.size();) { 1544514f5e3Sopenharmony_ci if (sections.find(sections_[i]) == sections.end()) { 1554514f5e3Sopenharmony_ci auto it = sections_.begin() + i; 1564514f5e3Sopenharmony_ci sections_.erase(it); 1574514f5e3Sopenharmony_ci continue; 1584514f5e3Sopenharmony_ci } 1594514f5e3Sopenharmony_ci i++; 1604514f5e3Sopenharmony_ci } 1614514f5e3Sopenharmony_ci} 1624514f5e3Sopenharmony_ci 1634514f5e3Sopenharmony_ciElfBuilder::~ElfBuilder() 1644514f5e3Sopenharmony_ci{ 1654514f5e3Sopenharmony_ci shStrTabPtr_ = nullptr; 1664514f5e3Sopenharmony_ci} 1674514f5e3Sopenharmony_ci 1684514f5e3Sopenharmony_ciuint32_t ElfBuilder::GetShIndex(ElfSecName section) const 1694514f5e3Sopenharmony_ci{ 1704514f5e3Sopenharmony_ci std::set<ElfSecName> secSet(sections_.begin(), sections_.end()); 1714514f5e3Sopenharmony_ci uint32_t idx = 1; 1724514f5e3Sopenharmony_ci for (ElfSecName sec : secSet) { 1734514f5e3Sopenharmony_ci if (sec == section) { 1744514f5e3Sopenharmony_ci return idx; 1754514f5e3Sopenharmony_ci } 1764514f5e3Sopenharmony_ci idx++; 1774514f5e3Sopenharmony_ci } 1784514f5e3Sopenharmony_ci return 0; 1794514f5e3Sopenharmony_ci} 1804514f5e3Sopenharmony_ci 1814514f5e3Sopenharmony_ciint ElfBuilder::GetSecNum() const 1824514f5e3Sopenharmony_ci{ 1834514f5e3Sopenharmony_ci return sections_.size() + 1; // add first empty section. 1844514f5e3Sopenharmony_ci} 1854514f5e3Sopenharmony_ci 1864514f5e3Sopenharmony_ci/* 1874514f5e3Sopenharmony_ciELF Header as follow: 1884514f5e3Sopenharmony_ciELF Header: 1894514f5e3Sopenharmony_ci Magic: 7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00 1904514f5e3Sopenharmony_ci Class: ELF64 1914514f5e3Sopenharmony_ci Data: 2's complement, little endian 1924514f5e3Sopenharmony_ci Version: 1 (current) 1934514f5e3Sopenharmony_ci OS/ABI: UNIX - System V 1944514f5e3Sopenharmony_ci ABI Version: 0 1954514f5e3Sopenharmony_ci Type: DYN (Shared object file) 1964514f5e3Sopenharmony_ci Machine: Advanced Micro Devices X86-64 1974514f5e3Sopenharmony_ci Version: 0x4000001 1984514f5e3Sopenharmony_ci Entry point address: 0x0 1994514f5e3Sopenharmony_ci Start of program headers: 16384 (bytes into file) 2004514f5e3Sopenharmony_ci Start of section headers: 64 (bytes into file) 2014514f5e3Sopenharmony_ci Flags: 0x0 2024514f5e3Sopenharmony_ci Size of this header: 64 (bytes) 2034514f5e3Sopenharmony_ci Size of program headers: 56 (bytes) 2044514f5e3Sopenharmony_ci Number of program headers: 2 2054514f5e3Sopenharmony_ci Size of section headers: 64 (bytes) 2064514f5e3Sopenharmony_ci Number of section headers: 7 2074514f5e3Sopenharmony_ci Section header string table index: 3 2084514f5e3Sopenharmony_ci*/ 2094514f5e3Sopenharmony_civoid ElfBuilder::PackELFHeader(llvm::ELF::Elf64_Ehdr &header, uint32_t version, Triple triple) 2104514f5e3Sopenharmony_ci{ 2114514f5e3Sopenharmony_ci if (memset_s(reinterpret_cast<void *>(&header), sizeof(llvm::ELF::Elf64_Ehdr), 0, 2124514f5e3Sopenharmony_ci sizeof(llvm::ELF::Elf64_Ehdr)) != EOK) { 2134514f5e3Sopenharmony_ci UNREACHABLE(); 2144514f5e3Sopenharmony_ci } 2154514f5e3Sopenharmony_ci header.e_ident[llvm::ELF::EI_MAG0] = llvm::ELF::ElfMagic[llvm::ELF::EI_MAG0]; 2164514f5e3Sopenharmony_ci header.e_ident[llvm::ELF::EI_MAG1] = llvm::ELF::ElfMagic[llvm::ELF::EI_MAG1]; 2174514f5e3Sopenharmony_ci header.e_ident[llvm::ELF::EI_MAG2] = llvm::ELF::ElfMagic[llvm::ELF::EI_MAG2]; 2184514f5e3Sopenharmony_ci header.e_ident[llvm::ELF::EI_MAG3] = llvm::ELF::ElfMagic[llvm::ELF::EI_MAG3]; 2194514f5e3Sopenharmony_ci header.e_ident[llvm::ELF::EI_CLASS] = llvm::ELF::ELFCLASS64; 2204514f5e3Sopenharmony_ci header.e_ident[llvm::ELF::EI_DATA] = llvm::ELF::ELFDATA2LSB; 2214514f5e3Sopenharmony_ci header.e_ident[llvm::ELF::EI_VERSION] = 1; 2224514f5e3Sopenharmony_ci 2234514f5e3Sopenharmony_ci header.e_type = llvm::ELF::ET_DYN; 2244514f5e3Sopenharmony_ci switch (triple) { 2254514f5e3Sopenharmony_ci case Triple::TRIPLE_AMD64: 2264514f5e3Sopenharmony_ci header.e_machine = llvm::ELF::EM_X86_64; 2274514f5e3Sopenharmony_ci break; 2284514f5e3Sopenharmony_ci case Triple::TRIPLE_ARM32: 2294514f5e3Sopenharmony_ci header.e_machine = llvm::ELF::EM_ARM; 2304514f5e3Sopenharmony_ci break; 2314514f5e3Sopenharmony_ci case Triple::TRIPLE_AARCH64: 2324514f5e3Sopenharmony_ci header.e_machine = llvm::ELF::EM_AARCH64; 2334514f5e3Sopenharmony_ci break; 2344514f5e3Sopenharmony_ci default: 2354514f5e3Sopenharmony_ci UNREACHABLE(); 2364514f5e3Sopenharmony_ci break; 2374514f5e3Sopenharmony_ci } 2384514f5e3Sopenharmony_ci header.e_version = version; 2394514f5e3Sopenharmony_ci // start of section headers 2404514f5e3Sopenharmony_ci header.e_shoff = sizeof(llvm::ELF::Elf64_Ehdr); 2414514f5e3Sopenharmony_ci // size of ehdr 2424514f5e3Sopenharmony_ci header.e_ehsize = sizeof(llvm::ELF::Elf64_Ehdr); 2434514f5e3Sopenharmony_ci // size of section headers 2444514f5e3Sopenharmony_ci header.e_shentsize = sizeof(llvm::ELF::Elf64_Shdr); 2454514f5e3Sopenharmony_ci // number of section headers 2464514f5e3Sopenharmony_ci header.e_shnum = GetSecNum(); 2474514f5e3Sopenharmony_ci // section header string table index 2484514f5e3Sopenharmony_ci header.e_shstrndx = static_cast<llvm::ELF::Elf64_Half>(GetShIndex(ElfSecName::SHSTRTAB)); 2494514f5e3Sopenharmony_ci // section header stub sec info index 2504514f5e3Sopenharmony_ci header.e_flags = static_cast<llvm::ELF::Elf64_Word>(GetShIndex(ElfSecName::ARK_MODULEINFO)); 2514514f5e3Sopenharmony_ci // phr 2524514f5e3Sopenharmony_ci header.e_phentsize = sizeof(llvm::ELF::Elf64_Phdr); 2534514f5e3Sopenharmony_ci header.e_phnum = GetSegmentNum(); 2544514f5e3Sopenharmony_ci} 2554514f5e3Sopenharmony_ci 2564514f5e3Sopenharmony_ciint ElfBuilder::GetSegmentNum() const 2574514f5e3Sopenharmony_ci{ 2584514f5e3Sopenharmony_ci const std::map<ElfSecName, std::pair<uint64_t, uint32_t>> §ions = GetFullSecInfo(); 2594514f5e3Sopenharmony_ci std::set<ElfSecName> segments; 2604514f5e3Sopenharmony_ci for (auto &s: sections) { 2614514f5e3Sopenharmony_ci ElfSection section = ElfSection(s.first); 2624514f5e3Sopenharmony_ci if (!section.ShouldDumpToAOTFile()) { 2634514f5e3Sopenharmony_ci continue; 2644514f5e3Sopenharmony_ci } 2654514f5e3Sopenharmony_ci auto it = sectionToSegment_.find(s.first); 2664514f5e3Sopenharmony_ci ASSERT(it != sectionToSegment_.end()); 2674514f5e3Sopenharmony_ci ElfSecName name = it->second; 2684514f5e3Sopenharmony_ci segments.insert(name); 2694514f5e3Sopenharmony_ci } 2704514f5e3Sopenharmony_ci return segments.size(); 2714514f5e3Sopenharmony_ci} 2724514f5e3Sopenharmony_ci 2734514f5e3Sopenharmony_civoid ElfBuilder::SetLastSection() 2744514f5e3Sopenharmony_ci{ 2754514f5e3Sopenharmony_ci const std::map<ElfSecName, std::pair<uint64_t, uint32_t>> §ions = GetFullSecInfo(); 2764514f5e3Sopenharmony_ci for (auto &s: sections) { 2774514f5e3Sopenharmony_ci ElfSection section = ElfSection(s.first); 2784514f5e3Sopenharmony_ci if (!section.ShouldDumpToAOTFile()) { 2794514f5e3Sopenharmony_ci continue; 2804514f5e3Sopenharmony_ci } 2814514f5e3Sopenharmony_ci auto it = sectionToSegment_.find(s.first); 2824514f5e3Sopenharmony_ci ASSERT(it != sectionToSegment_.end()); 2834514f5e3Sopenharmony_ci ElfSecName name = it->second; 2844514f5e3Sopenharmony_ci if (name == ElfSecName::TEXT) { 2854514f5e3Sopenharmony_ci lastCodeSection = std::max(lastCodeSection, s.first); 2864514f5e3Sopenharmony_ci } else { 2874514f5e3Sopenharmony_ci lastDataSection = std::max(lastDataSection, s.first); 2884514f5e3Sopenharmony_ci } 2894514f5e3Sopenharmony_ci } 2904514f5e3Sopenharmony_ci} 2914514f5e3Sopenharmony_ci 2924514f5e3Sopenharmony_cillvm::ELF::Elf64_Word ElfBuilder::FindShName(std::string name, uintptr_t strTabPtr, int strTabSize) 2934514f5e3Sopenharmony_ci{ 2944514f5e3Sopenharmony_ci llvm::ELF::Elf64_Word ans = -1; 2954514f5e3Sopenharmony_ci int len = static_cast<int>(name.size()); 2964514f5e3Sopenharmony_ci if (strTabSize < len + 1) { 2974514f5e3Sopenharmony_ci return ans; 2984514f5e3Sopenharmony_ci } 2994514f5e3Sopenharmony_ci LOG_ECMA(DEBUG) << " FindShName name:" << name.c_str() << std::endl; 3004514f5e3Sopenharmony_ci for (int i = 0; i < strTabSize - len + 1; ++i) { 3014514f5e3Sopenharmony_ci char *dst = reinterpret_cast<char *>(strTabPtr) + i; 3024514f5e3Sopenharmony_ci if (name.compare(dst) == 0) { 3034514f5e3Sopenharmony_ci return i; 3044514f5e3Sopenharmony_ci } 3054514f5e3Sopenharmony_ci } 3064514f5e3Sopenharmony_ci return ans; 3074514f5e3Sopenharmony_ci} 3084514f5e3Sopenharmony_ci 3094514f5e3Sopenharmony_cistd::pair<uint64_t, uint32_t> ElfBuilder::FindShStrTab() const 3104514f5e3Sopenharmony_ci{ 3114514f5e3Sopenharmony_ci const std::map<ElfSecName, std::pair<uint64_t, uint32_t>> §ions = GetFullSecInfo(); 3124514f5e3Sopenharmony_ci uint64_t shStrTabAddr = 0; 3134514f5e3Sopenharmony_ci uint32_t shStrTabSize = 0; 3144514f5e3Sopenharmony_ci for (auto &s: sections) { 3154514f5e3Sopenharmony_ci uint32_t curSecSize = des_[ShStrTableModuleDesIndex].GetSecSize(s.first); 3164514f5e3Sopenharmony_ci uint64_t curSecAddr = des_[ShStrTableModuleDesIndex].GetSecAddr(s.first); 3174514f5e3Sopenharmony_ci if (s.first == ElfSecName::SHSTRTAB) { 3184514f5e3Sopenharmony_ci shStrTabSize = curSecSize; 3194514f5e3Sopenharmony_ci shStrTabAddr = curSecAddr; 3204514f5e3Sopenharmony_ci break; 3214514f5e3Sopenharmony_ci } 3224514f5e3Sopenharmony_ci } 3234514f5e3Sopenharmony_ci return std::make_pair(shStrTabAddr, shStrTabSize); 3244514f5e3Sopenharmony_ci} 3254514f5e3Sopenharmony_ci 3264514f5e3Sopenharmony_civoid ElfBuilder::AllocateShdr(std::unique_ptr<llvm::ELF::Elf64_Shdr []> &shdr, const uint32_t &secNum) 3274514f5e3Sopenharmony_ci{ 3284514f5e3Sopenharmony_ci shdr = std::make_unique<llvm::ELF::Elf64_Shdr []>(secNum); 3294514f5e3Sopenharmony_ci if (memset_s(reinterpret_cast<void *>(&shdr[0]), 3304514f5e3Sopenharmony_ci sizeof(llvm::ELF::Elf64_Shdr), 3314514f5e3Sopenharmony_ci 0, 3324514f5e3Sopenharmony_ci sizeof(llvm::ELF::Elf64_Shdr)) != EOK) { 3334514f5e3Sopenharmony_ci UNREACHABLE(); 3344514f5e3Sopenharmony_ci } 3354514f5e3Sopenharmony_ci} 3364514f5e3Sopenharmony_ci 3374514f5e3Sopenharmony_cillvm::ELF::Elf64_Off ElfBuilder::ComputeEndAddrOfShdr(const uint32_t &secNum) const 3384514f5e3Sopenharmony_ci{ 3394514f5e3Sopenharmony_ci llvm::ELF::Elf64_Off curSecOffset = sizeof(llvm::ELF::Elf64_Ehdr) + secNum * sizeof(llvm::ELF::Elf64_Shdr); 3404514f5e3Sopenharmony_ci curSecOffset = AlignUp(curSecOffset, PageSize()); // not pagesize align will cause performance degradation 3414514f5e3Sopenharmony_ci return curSecOffset; 3424514f5e3Sopenharmony_ci} 3434514f5e3Sopenharmony_ci 3444514f5e3Sopenharmony_ciElfSecName ElfBuilder::GetSegmentName(const ElfSecName &secName) const 3454514f5e3Sopenharmony_ci{ 3464514f5e3Sopenharmony_ci auto it = sectionToSegment_.find(secName); 3474514f5e3Sopenharmony_ci ASSERT(it != sectionToSegment_.end()); 3484514f5e3Sopenharmony_ci ElfSecName segName = it->second; 3494514f5e3Sopenharmony_ci return segName; 3504514f5e3Sopenharmony_ci} 3514514f5e3Sopenharmony_ci 3524514f5e3Sopenharmony_civoid ElfBuilder::MergeTextSections(std::ofstream &file, 3534514f5e3Sopenharmony_ci std::vector<ModuleSectionDes::ModuleRegionInfo> &moduleInfo, 3544514f5e3Sopenharmony_ci llvm::ELF::Elf64_Off &curSecOffset) 3554514f5e3Sopenharmony_ci{ 3564514f5e3Sopenharmony_ci for (size_t i = 0; i < des_.size(); ++i) { 3574514f5e3Sopenharmony_ci ModuleSectionDes &des = des_[i]; 3584514f5e3Sopenharmony_ci ModuleSectionDes::ModuleRegionInfo &curInfo = moduleInfo[i]; 3594514f5e3Sopenharmony_ci uint32_t curSecSize = des.GetSecSize(ElfSecName::TEXT); 3604514f5e3Sopenharmony_ci uint64_t curSecAddr = des.GetSecAddr(ElfSecName::TEXT); 3614514f5e3Sopenharmony_ci curSecOffset = AlignUp(curSecOffset, AOTFileInfo::PAGE_ALIGN); 3624514f5e3Sopenharmony_ci file.seekp(curSecOffset); 3634514f5e3Sopenharmony_ci auto curModuleSec = des.GetSectionsInfo(); 3644514f5e3Sopenharmony_ci uint64_t rodataAddrBeforeText = 0; 3654514f5e3Sopenharmony_ci uint32_t rodataSizeBeforeText = 0; 3664514f5e3Sopenharmony_ci uint64_t rodataAddrAfterText = 0; 3674514f5e3Sopenharmony_ci uint32_t rodataSizeAfterText = 0; 3684514f5e3Sopenharmony_ci std::tie(rodataAddrBeforeText, rodataSizeBeforeText, rodataAddrAfterText, rodataSizeAfterText) = 3694514f5e3Sopenharmony_ci des.GetMergedRODataAddrAndSize(curSecAddr); 3704514f5e3Sopenharmony_ci if (rodataSizeBeforeText != 0) { 3714514f5e3Sopenharmony_ci file.write(reinterpret_cast<char *>(rodataAddrBeforeText), rodataSizeBeforeText); 3724514f5e3Sopenharmony_ci curInfo.rodataSizeBeforeText = rodataSizeBeforeText; 3734514f5e3Sopenharmony_ci curSecOffset += rodataSizeBeforeText; 3744514f5e3Sopenharmony_ci curSecOffset = AlignUp(curSecOffset, AOTFileInfo::TEXT_SEC_ALIGN); 3754514f5e3Sopenharmony_ci file.seekp(curSecOffset); 3764514f5e3Sopenharmony_ci } 3774514f5e3Sopenharmony_ci stubTextOffset_.emplace_back(curSecOffset); 3784514f5e3Sopenharmony_ci file.write(reinterpret_cast<char *>(curSecAddr), curSecSize); 3794514f5e3Sopenharmony_ci curInfo.textSize = curSecSize; 3804514f5e3Sopenharmony_ci curSecOffset += curSecSize; 3814514f5e3Sopenharmony_ci if (rodataSizeAfterText != 0) { 3824514f5e3Sopenharmony_ci curSecOffset = AlignUp(curSecOffset, AOTFileInfo::DATA_SEC_ALIGN); 3834514f5e3Sopenharmony_ci file.seekp(curSecOffset); 3844514f5e3Sopenharmony_ci file.write(reinterpret_cast<char *>(rodataAddrAfterText), rodataSizeAfterText); 3854514f5e3Sopenharmony_ci curInfo.rodataSizeAfterText = rodataSizeAfterText; 3864514f5e3Sopenharmony_ci curSecOffset += rodataSizeAfterText; 3874514f5e3Sopenharmony_ci } 3884514f5e3Sopenharmony_ci } 3894514f5e3Sopenharmony_ci} 3904514f5e3Sopenharmony_ci 3914514f5e3Sopenharmony_civoid ElfBuilder::MergeStrtabSections(std::ofstream &file, 3924514f5e3Sopenharmony_ci std::vector<ModuleSectionDes::ModuleRegionInfo> &moduleInfo, 3934514f5e3Sopenharmony_ci llvm::ELF::Elf64_Off &curSecOffset) 3944514f5e3Sopenharmony_ci{ 3954514f5e3Sopenharmony_ci for (size_t i = 0; i < des_.size(); ++i) { 3964514f5e3Sopenharmony_ci ModuleSectionDes &des = des_[i]; 3974514f5e3Sopenharmony_ci ModuleSectionDes::ModuleRegionInfo &curInfo = moduleInfo[i]; 3984514f5e3Sopenharmony_ci uint32_t curSecSize = des.GetSecSize(ElfSecName::STRTAB); 3994514f5e3Sopenharmony_ci uint64_t curSecAddr = des.GetSecAddr(ElfSecName::STRTAB); 4004514f5e3Sopenharmony_ci curInfo.strtabSize = curSecSize; 4014514f5e3Sopenharmony_ci file.write(reinterpret_cast<char *>(curSecAddr), curSecSize); 4024514f5e3Sopenharmony_ci curSecOffset += curSecSize; 4034514f5e3Sopenharmony_ci if (des.HasAsmStubStrTab()) { 4044514f5e3Sopenharmony_ci uint32_t asmStubStrTabSize = AddAsmStubStrTab(file, des.GetAsmStubELFInfo()); 4054514f5e3Sopenharmony_ci curSecOffset += asmStubStrTabSize; 4064514f5e3Sopenharmony_ci curInfo.strtabSize += asmStubStrTabSize; 4074514f5e3Sopenharmony_ci } 4084514f5e3Sopenharmony_ci } 4094514f5e3Sopenharmony_ci} 4104514f5e3Sopenharmony_ci 4114514f5e3Sopenharmony_civoid ElfBuilder::MergeSymtabSections(std::ofstream &file, 4124514f5e3Sopenharmony_ci std::vector<ModuleSectionDes::ModuleRegionInfo> &moduleInfo, 4134514f5e3Sopenharmony_ci llvm::ELF::Elf64_Off &curSecOffset, 4144514f5e3Sopenharmony_ci llvm::ELF::Elf64_Off &asmStubOffset) 4154514f5e3Sopenharmony_ci{ 4164514f5e3Sopenharmony_ci using Elf64_Sym = llvm::ELF::Elf64_Sym; 4174514f5e3Sopenharmony_ci uint32_t strTabSize = 0; 4184514f5e3Sopenharmony_ci uint32_t textSecIndex = GetShIndex(ElfSecName::ARK_ASMSTUB); 4194514f5e3Sopenharmony_ci for (size_t i = 0; i < des_.size(); ++i) { 4204514f5e3Sopenharmony_ci ModuleSectionDes &des = des_[i]; 4214514f5e3Sopenharmony_ci ModuleSectionDes::ModuleRegionInfo &curInfo = moduleInfo[i]; 4224514f5e3Sopenharmony_ci uint32_t curSecSize = des.GetSecSize(ElfSecName::SYMTAB); 4234514f5e3Sopenharmony_ci uint64_t curSecAddr = des.GetSecAddr(ElfSecName::SYMTAB); 4244514f5e3Sopenharmony_ci curInfo.symtabSize = curSecSize; 4254514f5e3Sopenharmony_ci file.write(reinterpret_cast<char *>(curSecAddr), curSecSize); 4264514f5e3Sopenharmony_ci curSecOffset += curSecSize; 4274514f5e3Sopenharmony_ci strTabSize += des.GetSecSize(ElfSecName::STRTAB); 4284514f5e3Sopenharmony_ci if (des.HasAsmStubStrTab()) { 4294514f5e3Sopenharmony_ci const std::vector<std::pair<std::string, uint32_t>> &asmStubELFInfo = des.GetAsmStubELFInfo(); 4304514f5e3Sopenharmony_ci ASSERT(asmStubELFInfo.size() > 0); 4314514f5e3Sopenharmony_ci uint32_t asmStubSymTabNum = asmStubELFInfo.size() - 1; 4324514f5e3Sopenharmony_ci std::unique_ptr<Elf64_Sym []> syms = std::make_unique<Elf64_Sym []>(asmStubSymTabNum); 4334514f5e3Sopenharmony_ci ASSERT(asmStubStrName_.size() == asmStubSymTabNum); 4344514f5e3Sopenharmony_ci for (size_t idx = 0; idx < asmStubSymTabNum; ++idx) { 4354514f5e3Sopenharmony_ci Elf64_Sym &sym = syms[idx]; 4364514f5e3Sopenharmony_ci sym.setBindingAndType(llvm::ELF::STB_GLOBAL, llvm::ELF::STT_FUNC); 4374514f5e3Sopenharmony_ci sym.st_shndx = static_cast<uint16_t>(textSecIndex); 4384514f5e3Sopenharmony_ci sym.st_value = asmStubELFInfo[idx].second + asmStubOffset; 4394514f5e3Sopenharmony_ci sym.st_name = asmStubStrName_[idx]; 4404514f5e3Sopenharmony_ci sym.st_name += strTabSize; 4414514f5e3Sopenharmony_ci sym.st_other = llvm::ELF::STV_DEFAULT; 4424514f5e3Sopenharmony_ci sym.st_size = asmStubELFInfo[idx + 1].second - asmStubELFInfo[idx].second; 4434514f5e3Sopenharmony_ci } 4444514f5e3Sopenharmony_ci uint32_t asmStubSymTabSize = asmStubSymTabNum * sizeof(llvm::ELF::Elf64_Sym); 4454514f5e3Sopenharmony_ci file.write(reinterpret_cast<char *>(syms.get()), asmStubSymTabSize); 4464514f5e3Sopenharmony_ci curInfo.symtabSize += asmStubSymTabSize; 4474514f5e3Sopenharmony_ci curSecOffset += asmStubSymTabSize; 4484514f5e3Sopenharmony_ci } 4494514f5e3Sopenharmony_ci } 4504514f5e3Sopenharmony_ci} 4514514f5e3Sopenharmony_ci 4524514f5e3Sopenharmony_civoid ElfBuilder::MergeArkStackMapSections(std::ofstream &file, 4534514f5e3Sopenharmony_ci std::vector<ModuleSectionDes::ModuleRegionInfo> &moduleInfo, 4544514f5e3Sopenharmony_ci llvm::ELF::Elf64_Off &curSecOffset) 4554514f5e3Sopenharmony_ci{ 4564514f5e3Sopenharmony_ci for (size_t i = 0; i < des_.size(); ++i) { 4574514f5e3Sopenharmony_ci ModuleSectionDes &des = des_[i]; 4584514f5e3Sopenharmony_ci ModuleSectionDes::ModuleRegionInfo &curInfo = moduleInfo[i]; 4594514f5e3Sopenharmony_ci uint32_t curSecSize = des.GetSecSize(ElfSecName::ARK_STACKMAP); 4604514f5e3Sopenharmony_ci uint64_t curSecAddr = des.GetSecAddr(ElfSecName::ARK_STACKMAP); 4614514f5e3Sopenharmony_ci uint32_t index = des.GetStartIndex(); 4624514f5e3Sopenharmony_ci uint32_t cnt = des.GetFuncCount(); 4634514f5e3Sopenharmony_ci curInfo.startIndex = index; 4644514f5e3Sopenharmony_ci curInfo.funcCount = cnt; 4654514f5e3Sopenharmony_ci curInfo.stackMapSize = curSecSize; 4664514f5e3Sopenharmony_ci file.write(reinterpret_cast<char *>(curSecAddr), curSecSize); 4674514f5e3Sopenharmony_ci curSecOffset += curSecSize; 4684514f5e3Sopenharmony_ci } 4694514f5e3Sopenharmony_ci} 4704514f5e3Sopenharmony_ci 4714514f5e3Sopenharmony_civoid ElfBuilder::FixSymtab(llvm::ELF::Elf64_Shdr* shdr) 4724514f5e3Sopenharmony_ci{ 4734514f5e3Sopenharmony_ci using Elf64_Sym = llvm::ELF::Elf64_Sym; 4744514f5e3Sopenharmony_ci ASSERT(stubTextOffset_.size() == des_.size()); 4754514f5e3Sopenharmony_ci 4764514f5e3Sopenharmony_ci uint32_t secNum = static_cast<uint32_t>(GetSecNum()); 4774514f5e3Sopenharmony_ci uint32_t shStrTabIndex = GetShIndex(ElfSecName::SHSTRTAB); 4784514f5e3Sopenharmony_ci uint32_t strTabIndex = GetShIndex(ElfSecName::STRTAB); 4794514f5e3Sopenharmony_ci uint32_t textSecIndex = GetShIndex(ElfSecName::TEXT); 4804514f5e3Sopenharmony_ci 4814514f5e3Sopenharmony_ci uint32_t strTabSize = 0; 4824514f5e3Sopenharmony_ci int firstGlobal = -1; 4834514f5e3Sopenharmony_ci uint32_t count = 0; 4844514f5e3Sopenharmony_ci 4854514f5e3Sopenharmony_ci for (size_t idx = 0; idx < des_.size(); ++idx) { 4864514f5e3Sopenharmony_ci uint32_t secSize = des_[idx].GetSecSize(ElfSecName::SYMTAB); 4874514f5e3Sopenharmony_ci uint64_t secAddr = des_[idx].GetSecAddr(ElfSecName::SYMTAB); 4884514f5e3Sopenharmony_ci Elf64_Sym *syms = reinterpret_cast<Elf64_Sym*>(secAddr); 4894514f5e3Sopenharmony_ci size_t n = secSize / sizeof(Elf64_Sym); 4904514f5e3Sopenharmony_ci for (size_t i = 0; i < n; ++i) { 4914514f5e3Sopenharmony_ci Elf64_Sym* sy = &syms[i]; 4924514f5e3Sopenharmony_ci if (sy->getBinding() == llvm::ELF::STB_GLOBAL && firstGlobal == -1) { 4934514f5e3Sopenharmony_ci firstGlobal = static_cast<int>(count); 4944514f5e3Sopenharmony_ci } 4954514f5e3Sopenharmony_ci if (sy->getType() == llvm::ELF::STT_SECTION) { 4964514f5e3Sopenharmony_ci sy->st_shndx = static_cast<uint16_t>(shStrTabIndex); 4974514f5e3Sopenharmony_ci } else if (sy->getType() == llvm::ELF::STT_FUNC) { 4984514f5e3Sopenharmony_ci sy->st_shndx = static_cast<uint16_t>(textSecIndex); 4994514f5e3Sopenharmony_ci sy->st_value += stubTextOffset_[idx]; 5004514f5e3Sopenharmony_ci } 5014514f5e3Sopenharmony_ci if (sy->st_shndx > secNum) { 5024514f5e3Sopenharmony_ci sy->st_shndx = 0; 5034514f5e3Sopenharmony_ci } 5044514f5e3Sopenharmony_ci sy->st_name += strTabSize; 5054514f5e3Sopenharmony_ci count++; 5064514f5e3Sopenharmony_ci } 5074514f5e3Sopenharmony_ci strTabSize += des_[idx].GetSecSize(ElfSecName::STRTAB); 5084514f5e3Sopenharmony_ci } 5094514f5e3Sopenharmony_ci shdr->sh_info = static_cast<uint32_t>(firstGlobal); 5104514f5e3Sopenharmony_ci shdr->sh_link = strTabIndex; 5114514f5e3Sopenharmony_ci} 5124514f5e3Sopenharmony_ci 5134514f5e3Sopenharmony_ci/* 5144514f5e3Sopenharmony_ci 5154514f5e3Sopenharmony_cisection of aot.an layout as follows: 5164514f5e3Sopenharmony_ciThere are 7 section headers, starting at offset 0x40: 5174514f5e3Sopenharmony_ci 5184514f5e3Sopenharmony_ciSection Headers: 5194514f5e3Sopenharmony_ci [Nr] Name Type Address Offset Size EntSize Flags Link Info Align 5204514f5e3Sopenharmony_ci [ 0] NULL 0000000000000000 00000000 0000000000000000 0000000000000000 0 0 0 5214514f5e3Sopenharmony_ci [ 1] .text PROGBITS 0000000000001000 00001000 0000000000000f61 0000000000000000 AX 0 0 16 5224514f5e3Sopenharmony_ci [ 2] .strtab STRTAB 0000000000002000 00002000 0000000000000187 0000000000000000 A 0 0 1 5234514f5e3Sopenharmony_ci [ 3] .symtab SYMTAB 0000000000002188 00002188 00000000000001c8 0000000000000018 A 1 0 8 5244514f5e3Sopenharmony_ci [ 4] .shstrtab STRTAB 0000000000002350 00002350 000000000000003f 0000000000000000 A 0 0 8 5254514f5e3Sopenharmony_ci [ 5] .ark_funcentry PROGBITS 0000000000002390 00002390 00000000000006c0 0000000000000000 A 0 0 8 5264514f5e3Sopenharmony_ci [ 6] .ark_stackmaps PROGBITS 0000000000002a50 00002a50 000000000000070e 0000000000000000 A 0 0 8 5274514f5e3Sopenharmony_ci 5284514f5e3Sopenharmony_cisection of stub.an layout as follows: 5294514f5e3Sopenharmony_ciThere are 7 section headers, starting at offset 0x40: 5304514f5e3Sopenharmony_ci 5314514f5e3Sopenharmony_ci [Nr] Name Type Address Offset Size EntSize Flags Link Info Align 5324514f5e3Sopenharmony_ci [ 0] NULL 0000000000000000 00000000 0000000000000000 0000000000000000 0 0 0 5334514f5e3Sopenharmony_ci [ 1] .text PROGBITS 0000000000001000 00001000 000000000008225e 0000000000000000 AX 0 0 16 5344514f5e3Sopenharmony_ci [ 2] .ark_asmstub PROGBITS 0000000000083260 00083260 0000000000002dc0 0000000000000000 AX 0 0 8 5354514f5e3Sopenharmony_ci [ 3] .shstrtab STRTAB 0000000000087000 00087000 000000000000004c 0000000000000000 A 0 0 8 5364514f5e3Sopenharmony_ci [ 4] .ark_funcentry PROGBITS 0000000000087050 00087050 0000000000023ca0 0000000000000000 A 0 0 8 5374514f5e3Sopenharmony_ci [ 5] .ark_stackmaps PROGBITS 00000000000aacf0 000aacf0 0000000000011e90 0000000000000000 A 0 0 8 5384514f5e3Sopenharmony_ci [ 6] .ark_moduleinfo PROGBITS 00000000000bcb80 000bcb80 000000000000003c 0000000000000000 A 0 0 8 5394514f5e3Sopenharmony_ci 5404514f5e3Sopenharmony_ciKey to Flags: 5414514f5e3Sopenharmony_ci W (write), A (alloc), X (execute), M (merge), S (strings), I (info), 5424514f5e3Sopenharmony_ci L (link order), O (extra OS processing required), G (group), T (TLS), 5434514f5e3Sopenharmony_ci C (compressed), x (unknown), o (OS specific), E (exclude), 5444514f5e3Sopenharmony_ci D (mbind), l (large), p (processor specific) 5454514f5e3Sopenharmony_ci*/ 5464514f5e3Sopenharmony_civoid ElfBuilder::PackELFSections(std::ofstream &file) 5474514f5e3Sopenharmony_ci{ 5484514f5e3Sopenharmony_ci uint32_t moduleNum = des_.size(); 5494514f5e3Sopenharmony_ci const std::map<ElfSecName, std::pair<uint64_t, uint32_t>> §ions = GetFullSecInfo(); 5504514f5e3Sopenharmony_ci uint32_t secNum = sections.size() + 1; // 1 : section id = 0 is null section 5514514f5e3Sopenharmony_ci std::unique_ptr<llvm::ELF::Elf64_Shdr []> shdr; 5524514f5e3Sopenharmony_ci AllocateShdr(shdr, secNum); 5534514f5e3Sopenharmony_ci std::vector<ModuleSectionDes::ModuleRegionInfo> moduleInfo(moduleNum); 5544514f5e3Sopenharmony_ci llvm::ELF::Elf64_Off curSecOffset = ComputeEndAddrOfShdr(secNum); 5554514f5e3Sopenharmony_ci file.seekp(curSecOffset); 5564514f5e3Sopenharmony_ci 5574514f5e3Sopenharmony_ci int i = static_cast<int>(GetShIndex(ElfSecName::TEXT)); 5584514f5e3Sopenharmony_ci auto shStrTab = FindShStrTab(); 5594514f5e3Sopenharmony_ci 5604514f5e3Sopenharmony_ci for (auto const &[secName, secInfo] : sections) { 5614514f5e3Sopenharmony_ci auto &curShdr = shdr[i]; 5624514f5e3Sopenharmony_ci ElfSection section = ElfSection(secName); 5634514f5e3Sopenharmony_ci if (!section.ShouldDumpToAOTFile()) { 5644514f5e3Sopenharmony_ci continue; 5654514f5e3Sopenharmony_ci } 5664514f5e3Sopenharmony_ci curShdr.sh_addralign = sectionToAlign_[secName]; 5674514f5e3Sopenharmony_ci curSecOffset = AlignUp(curSecOffset, curShdr.sh_addralign); 5684514f5e3Sopenharmony_ci file.seekp(curSecOffset); 5694514f5e3Sopenharmony_ci ElfSecName segName = GetSegmentName(secName); 5704514f5e3Sopenharmony_ci segments_.insert(segName); 5714514f5e3Sopenharmony_ci std::string secNameStr = ModuleSectionDes::GetSecName(secName); 5724514f5e3Sopenharmony_ci // text section address needs 16 bytes alignment 5734514f5e3Sopenharmony_ci if (secName == ElfSecName::TEXT) { 5744514f5e3Sopenharmony_ci curSecOffset = AlignUp(curSecOffset, AOTFileInfo::PAGE_ALIGN); 5754514f5e3Sopenharmony_ci file.seekp(curSecOffset); 5764514f5e3Sopenharmony_ci } 5774514f5e3Sopenharmony_ci llvm::ELF::Elf64_Word shName = FindShName(secNameStr, shStrTab.first, shStrTab.second); 5784514f5e3Sopenharmony_ci ASSERT(shName != static_cast<llvm::ELF::Elf64_Word>(-1)); 5794514f5e3Sopenharmony_ci curShdr.sh_name = shName; 5804514f5e3Sopenharmony_ci curShdr.sh_type = section.Type(); 5814514f5e3Sopenharmony_ci curShdr.sh_flags = section.Flag(); 5824514f5e3Sopenharmony_ci curShdr.sh_addr = curSecOffset; 5834514f5e3Sopenharmony_ci curShdr.sh_offset = static_cast<uint64_t>(curSecOffset); 5844514f5e3Sopenharmony_ci curShdr.sh_info = 0; 5854514f5e3Sopenharmony_ci curShdr.sh_link = static_cast<uint32_t>(section.Link()); 5864514f5e3Sopenharmony_ci sectionToFileOffset_[secName] = static_cast<uintptr_t>(file.tellp()); 5874514f5e3Sopenharmony_ci switch (secName) { 5884514f5e3Sopenharmony_ci case ElfSecName::ARK_MODULEINFO: { 5894514f5e3Sopenharmony_ci uint32_t curSecSize = sizeof(ModuleSectionDes::ModuleRegionInfo) * moduleInfo.size(); 5904514f5e3Sopenharmony_ci file.write(reinterpret_cast<char *>(moduleInfo.data()), curSecSize); 5914514f5e3Sopenharmony_ci curSecOffset += curSecSize; 5924514f5e3Sopenharmony_ci curShdr.sh_size = curSecSize; 5934514f5e3Sopenharmony_ci break; 5944514f5e3Sopenharmony_ci } 5954514f5e3Sopenharmony_ci case ElfSecName::TEXT: { 5964514f5e3Sopenharmony_ci uint32_t curSize = curSecOffset; 5974514f5e3Sopenharmony_ci MergeTextSections(file, moduleInfo, curSecOffset); 5984514f5e3Sopenharmony_ci curShdr.sh_size = curSecOffset - curSize; 5994514f5e3Sopenharmony_ci break; 6004514f5e3Sopenharmony_ci } 6014514f5e3Sopenharmony_ci case ElfSecName::ARK_STACKMAP: { 6024514f5e3Sopenharmony_ci uint32_t curSize = curSecOffset; 6034514f5e3Sopenharmony_ci MergeArkStackMapSections(file, moduleInfo, curSecOffset); 6044514f5e3Sopenharmony_ci curShdr.sh_size = curSecOffset - curSize; 6054514f5e3Sopenharmony_ci break; 6064514f5e3Sopenharmony_ci } 6074514f5e3Sopenharmony_ci case ElfSecName::STRTAB: { 6084514f5e3Sopenharmony_ci uint32_t curSize = curSecOffset; 6094514f5e3Sopenharmony_ci MergeStrtabSections(file, moduleInfo, curSecOffset); 6104514f5e3Sopenharmony_ci curShdr.sh_size = curSecOffset - curSize; 6114514f5e3Sopenharmony_ci break; 6124514f5e3Sopenharmony_ci } 6134514f5e3Sopenharmony_ci case ElfSecName::SYMTAB: { 6144514f5e3Sopenharmony_ci FixSymtab(&curShdr); 6154514f5e3Sopenharmony_ci uint32_t curSize = curSecOffset; 6164514f5e3Sopenharmony_ci uint32_t asmSecIndex = GetShIndex(ElfSecName::ARK_ASMSTUB); 6174514f5e3Sopenharmony_ci MergeSymtabSections(file, moduleInfo, curSecOffset, shdr[asmSecIndex].sh_offset); 6184514f5e3Sopenharmony_ci curShdr.sh_size = curSecOffset - curSize; 6194514f5e3Sopenharmony_ci break; 6204514f5e3Sopenharmony_ci } 6214514f5e3Sopenharmony_ci case ElfSecName::SHSTRTAB: 6224514f5e3Sopenharmony_ci case ElfSecName::ARK_FUNCENTRY: 6234514f5e3Sopenharmony_ci case ElfSecName::ARK_ASMSTUB: { 6244514f5e3Sopenharmony_ci uint32_t curSecSize = des_[FullSecIndex].GetSecSize(secName); 6254514f5e3Sopenharmony_ci uint64_t curSecAddr = des_[FullSecIndex].GetSecAddr(secName); 6264514f5e3Sopenharmony_ci file.write(reinterpret_cast<char *>(curSecAddr), curSecSize); 6274514f5e3Sopenharmony_ci curSecOffset += curSecSize; 6284514f5e3Sopenharmony_ci curShdr.sh_size = curSecSize; 6294514f5e3Sopenharmony_ci break; 6304514f5e3Sopenharmony_ci } 6314514f5e3Sopenharmony_ci default: { 6324514f5e3Sopenharmony_ci LOG_ECMA(FATAL) << "this section should not dump to an file"; 6334514f5e3Sopenharmony_ci break; 6344514f5e3Sopenharmony_ci } 6354514f5e3Sopenharmony_ci } 6364514f5e3Sopenharmony_ci if (secName == lastDataSection || secName == lastCodeSection) { 6374514f5e3Sopenharmony_ci curSecOffset = AlignUp(curSecOffset, PageSize()); 6384514f5e3Sopenharmony_ci file.seekp(curSecOffset); 6394514f5e3Sopenharmony_ci } 6404514f5e3Sopenharmony_ci curShdr.sh_entsize = static_cast<uint64_t>(section.Entsize()); 6414514f5e3Sopenharmony_ci sectionToShdr_[secName] = curShdr; 6424514f5e3Sopenharmony_ci LOG_COMPILER(DEBUG) << " shdr[i].sh_entsize " << std::hex << curShdr.sh_entsize << std::endl; 6434514f5e3Sopenharmony_ci ++i; 6444514f5e3Sopenharmony_ci } 6454514f5e3Sopenharmony_ci uint32_t secEnd = static_cast<uint32_t>(file.tellp()); 6464514f5e3Sopenharmony_ci file.seekp(sizeof(llvm::ELF::Elf64_Ehdr)); 6474514f5e3Sopenharmony_ci file.write(reinterpret_cast<char *>(shdr.get()), secNum * sizeof(llvm::ELF::Elf64_Shdr)); 6484514f5e3Sopenharmony_ci file.seekp(secEnd); 6494514f5e3Sopenharmony_ci} 6504514f5e3Sopenharmony_ci 6514514f5e3Sopenharmony_ciunsigned ElfBuilder::GetPFlag(ElfSecName segment) const 6524514f5e3Sopenharmony_ci{ 6534514f5e3Sopenharmony_ci return segmentToFlag_.at(segment); 6544514f5e3Sopenharmony_ci} 6554514f5e3Sopenharmony_ci 6564514f5e3Sopenharmony_ci/* 6574514f5e3Sopenharmony_cisegment layout as follows: 6584514f5e3Sopenharmony_ciAn Elf file 6594514f5e3Sopenharmony_ciEntry point 0x0 6604514f5e3Sopenharmony_ciThere are 2 program headers, starting at offset 16384 6614514f5e3Sopenharmony_ci 6624514f5e3Sopenharmony_ciProgram Headers: 6634514f5e3Sopenharmony_ci Type Offset VirtAddr PhysAddr FileSiz MemSiz Flags Align 6644514f5e3Sopenharmony_ci LOAD 0x0000000000001000 0x0000000000001000 0x0000000000001000 0x0000000000000f61 0x0000000000001000 R E 0x1000 6654514f5e3Sopenharmony_ci LOAD 0x0000000000002000 0x0000000000002000 0x0000000000002000 0x000000000000115e 0x0000000000002000 R 0x1000 6664514f5e3Sopenharmony_ci 6674514f5e3Sopenharmony_ci Section to Segment mapping: 6684514f5e3Sopenharmony_ci Segment Sections... 6694514f5e3Sopenharmony_ci 00 .text 6704514f5e3Sopenharmony_ci 01 .strtab .symtab .shstrtab .ark_funcentry .ark_stackmaps 6714514f5e3Sopenharmony_ci------------------------------------------------------------------------------------------------------------------------------ 6724514f5e3Sopenharmony_ciStub Elf file 6734514f5e3Sopenharmony_ciEntry point 0x0 6744514f5e3Sopenharmony_ciThere are 2 program headers, starting at offset 770048 6754514f5e3Sopenharmony_ci 6764514f5e3Sopenharmony_ciProgram Headers: 6774514f5e3Sopenharmony_ci Type Offset VirtAddr PhysAddr FileSiz MemSiz Flags Align 6784514f5e3Sopenharmony_ci LOAD 0x0000000000001000 0x0000000000001000 0x0000000000001000 0x0000000000085020 0x0000000000086000 R E 0x1000 6794514f5e3Sopenharmony_ci LOAD 0x0000000000087000 0x0000000000087000 0x0000000000087000 0x0000000000035bbc 0x0000000000036000 R 0x1000 6804514f5e3Sopenharmony_ci 6814514f5e3Sopenharmony_ci Section to Segment mapping: 6824514f5e3Sopenharmony_ci Segment Sections... 6834514f5e3Sopenharmony_ci 00 .text .ark_asmstub 6844514f5e3Sopenharmony_ci 01 .shstrtab .ark_funcentry .ark_stackmaps .ark_moduleinfo 6854514f5e3Sopenharmony_ci*/ 6864514f5e3Sopenharmony_civoid ElfBuilder::PackELFSegment(std::ofstream &file) 6874514f5e3Sopenharmony_ci{ 6884514f5e3Sopenharmony_ci llvm::ELF::Elf64_Off e_phoff = static_cast<uint64_t>(file.tellp()); 6894514f5e3Sopenharmony_ci long phoff = (long)offsetof(struct llvm::ELF::Elf64_Ehdr, e_phoff); 6904514f5e3Sopenharmony_ci // write Elf32_Off e_phoff 6914514f5e3Sopenharmony_ci file.seekp(phoff); 6924514f5e3Sopenharmony_ci file.write(reinterpret_cast<char *>(&e_phoff), sizeof(e_phoff)); 6934514f5e3Sopenharmony_ci file.seekp(static_cast<long>(e_phoff)); 6944514f5e3Sopenharmony_ci 6954514f5e3Sopenharmony_ci int segNum = GetSegmentNum(); 6964514f5e3Sopenharmony_ci auto phdrs = std::make_unique<llvm::ELF::Elf64_Phdr []>(segNum); 6974514f5e3Sopenharmony_ci std::map<ElfSecName, llvm::ELF::Elf64_Off> segmentToMaxOffset; 6984514f5e3Sopenharmony_ci std::map<ElfSecName, llvm::ELF::Elf64_Off> segmentToMaxAddress; 6994514f5e3Sopenharmony_ci std::set<ElfSecName> segments; 7004514f5e3Sopenharmony_ci // SecName -> addr & size 7014514f5e3Sopenharmony_ci const std::map<ElfSecName, std::pair<uint64_t, uint32_t>> §ions = GetFullSecInfo(); 7024514f5e3Sopenharmony_ci llvm::ELF::Elf64_Off offset = e_phoff; 7034514f5e3Sopenharmony_ci for (auto &s: sections) { 7044514f5e3Sopenharmony_ci ElfSection section = ElfSection(s.first); 7054514f5e3Sopenharmony_ci if (!section.ShouldDumpToAOTFile()) { 7064514f5e3Sopenharmony_ci continue; 7074514f5e3Sopenharmony_ci } 7084514f5e3Sopenharmony_ci auto it = sectionToSegment_.find(s.first); 7094514f5e3Sopenharmony_ci ASSERT(it != sectionToSegment_.end()); 7104514f5e3Sopenharmony_ci ElfSecName segName = it->second; 7114514f5e3Sopenharmony_ci segments.insert(segName); 7124514f5e3Sopenharmony_ci if (segmentToMaxOffset.find(segName) == segmentToMaxOffset.end()) { 7134514f5e3Sopenharmony_ci segmentToMaxOffset[segName] = 0; 7144514f5e3Sopenharmony_ci } 7154514f5e3Sopenharmony_ci segmentToMaxOffset[segName] = 7164514f5e3Sopenharmony_ci std::max(segmentToMaxOffset[segName], sectionToShdr_[s.first].sh_offset + sectionToShdr_[s.first].sh_size); 7174514f5e3Sopenharmony_ci segmentToMaxAddress[segName] = 7184514f5e3Sopenharmony_ci std::max(segmentToMaxAddress[segName], sectionToShdr_[s.first].sh_addr + sectionToShdr_[s.first].sh_size); 7194514f5e3Sopenharmony_ci offset = std::min(offset, sectionToShdr_[s.first].sh_offset); 7204514f5e3Sopenharmony_ci } 7214514f5e3Sopenharmony_ci int phdrIndex = 0; 7224514f5e3Sopenharmony_ci llvm::ELF::Elf64_Addr addr = offset; 7234514f5e3Sopenharmony_ci for (auto &it: segments) { 7244514f5e3Sopenharmony_ci ElfSecName name = it; 7254514f5e3Sopenharmony_ci phdrs[phdrIndex].p_align = PageSize(); 7264514f5e3Sopenharmony_ci phdrs[phdrIndex].p_type = llvm::ELF::PT_LOAD; 7274514f5e3Sopenharmony_ci phdrs[phdrIndex].p_flags = GetPFlag(name); 7284514f5e3Sopenharmony_ci offset = AlignUp(offset, PageSize()); 7294514f5e3Sopenharmony_ci phdrs[phdrIndex].p_offset = offset; 7304514f5e3Sopenharmony_ci phdrs[phdrIndex].p_vaddr = addr % phdrs[phdrIndex].p_align == 0 ? 7314514f5e3Sopenharmony_ci addr : (addr / phdrs[phdrIndex].p_align + 1) * phdrs[phdrIndex].p_align; 7324514f5e3Sopenharmony_ci phdrs[phdrIndex].p_paddr = phdrs[phdrIndex].p_vaddr; 7334514f5e3Sopenharmony_ci 7344514f5e3Sopenharmony_ci phdrs[phdrIndex].p_filesz = segmentToMaxOffset[name] - phdrs[phdrIndex].p_offset; 7354514f5e3Sopenharmony_ci phdrs[phdrIndex].p_memsz = segmentToMaxAddress[name] - phdrs[phdrIndex].p_vaddr; 7364514f5e3Sopenharmony_ci phdrs[phdrIndex].p_memsz = AlignUp(phdrs[phdrIndex].p_memsz, PageSize()); 7374514f5e3Sopenharmony_ci addr = phdrs[phdrIndex].p_vaddr + phdrs[phdrIndex].p_memsz; 7384514f5e3Sopenharmony_ci offset += phdrs[phdrIndex].p_filesz; 7394514f5e3Sopenharmony_ci ++phdrIndex; 7404514f5e3Sopenharmony_ci } 7414514f5e3Sopenharmony_ci file.write(reinterpret_cast<char *>(phdrs.get()), sizeof(llvm::ELF::Elf64_Phdr) * segNum); 7424514f5e3Sopenharmony_ci} 7434514f5e3Sopenharmony_ci} // namespace panda::ecmascript 744