diff --git a/BUILD.gn b/BUILD.gn index d4a040a959..32e14564b0 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -892,6 +892,14 @@ if (is_mingw) { } ohos_source_set("libark_jsruntime_set") { + if (is_ohos && is_standard_system) { + stub_an_file_path = "/system/lib64/module/stub.an" + } else { + stub_an_file_path = + rebase_path("$root_gen_dir/arkcompiler/ets_runtime/stub.an") + } + defines = [ "STUB_AN_FILE=\"${stub_an_file_path}\"" ] + sources = ecma_source sources += ecma_profiler_source sources += ecma_debugger_source @@ -950,6 +958,13 @@ ohos_source_set("libark_jsruntime_test_set") { sources += ecma_platform_source defines = [ "OHOS_UNIT_TEST" ] + if (is_ohos && is_standard_system) { + stub_an_file_path = "/system/lib64/module/stub.an" + } else { + stub_an_file_path = + rebase_path("$root_gen_dir/arkcompiler/ets_runtime/stub.an") + } + defines += [ "STUB_AN_FILE=\"${stub_an_file_path}\"" ] deps = [ "$ark_root/libpandafile:arkfile_header_deps", "$ark_third_party_root/icu/icu4c:shared_icui18n", diff --git a/ecmascript/compiler/aot_file/an_file_info.cpp b/ecmascript/compiler/aot_file/an_file_info.cpp index 47b6b87312..3b20213e34 100644 --- a/ecmascript/compiler/aot_file/an_file_info.cpp +++ b/ecmascript/compiler/aot_file/an_file_info.cpp @@ -30,26 +30,20 @@ void AnFileInfo::Save(const std::string &filename, Triple triple) return; } - if (totalCodeSize_ == 0) { - LOG_HOST_TOOL_ERROR << "The an file generated by the aot compiler is empty! " - << "Maybe file in apPath is empty or all methods in ap file are mismatched"; - LOG_COMPILER(FATAL) << "error: code size of generated an file is empty!"; - } - std::ofstream file(realPath.c_str(), std::ofstream::binary); ASSERT(GetCodeUnitsNum() == 1); + SetStubNum(entries_.size()); ModuleSectionDes &des = des_[0]; // add section - uint64_t addr = reinterpret_cast(entries_.data()); - entryNum_ = entries_.size(); - uint32_t size = sizeof(FuncEntryDes) * entryNum_; - des.SetSecAddr(addr, ElfSecName::ARK_FUNCENTRY); - des.SetSecSize(size, ElfSecName::ARK_FUNCENTRY); - ElfBuilder builder(des); + uint64_t funcEntryAddr = reinterpret_cast(entries_.data()); + uint32_t funcEntrySize = sizeof(FuncEntryDes) * entryNum_; + des.SetSecAddrAndSize(ElfSecName::ARK_FUNCENTRY, funcEntryAddr, funcEntrySize); + + ElfBuilder builder(des_, GetDumpSectionNames()); llvm::ELF::Elf64_Ehdr header; - builder.PackELFHeader(header, base::FileHeader::ToVersionNumber(AOTFileVersion::AI_VERSION), triple); - file.write(reinterpret_cast(&header), sizeof(llvm::ELF::Elf64_Shdr)); - builder.PackELFSections(file); + builder.PackELFHeader(header, base::FileHeader::ToVersionNumber(AOTFileVersion::AN_VERSION), triple); + file.write(reinterpret_cast(&header), sizeof(llvm::ELF::Elf64_Ehdr)); + builder.PackAnELFSections(file); builder.PackELFSegment(file); file.close(); } @@ -76,7 +70,7 @@ bool AnFileInfo::Load(const std::string &filename) ElfReader reader(fileMapMem_); std::vector secs = GetDumpSectionNames(); - if (!reader.VerifyELFHeader(base::FileHeader::ToVersionNumber(AOTFileVersion::AI_VERSION), + if (!reader.VerifyELFHeader(base::FileHeader::ToVersionNumber(AOTFileVersion::AN_VERSION), AOTFileVersion::AN_STRICT_MATCH)) { return false; } @@ -120,9 +114,9 @@ void AnFileInfo::RelocateTextSection() const std::vector &AnFileInfo::GetDumpSectionNames() { - static const std::vector secNames = {ElfSecName::RODATA_CST8, ElfSecName::TEXT, - ElfSecName::STRTAB, ElfSecName::SYMTAB, - ElfSecName::ARK_STACKMAP, ElfSecName::ARK_FUNCENTRY}; + static const std::vector secNames = {ElfSecName::RODATA_CST8, ElfSecName::TEXT, + ElfSecName::STRTAB, ElfSecName::ARK_STACKMAP, + ElfSecName::ARK_FUNCENTRY}; return secNames; } diff --git a/ecmascript/compiler/aot_file/binary_buffer_parser.cpp b/ecmascript/compiler/aot_file/binary_buffer_parser.cpp index 10ff70f0e6..824d213bcf 100644 --- a/ecmascript/compiler/aot_file/binary_buffer_parser.cpp +++ b/ecmascript/compiler/aot_file/binary_buffer_parser.cpp @@ -29,6 +29,12 @@ void BinaryBufferParser::ParseBuffer(void *dst, uint32_t count) } } +void BinaryBufferParser::ParseBuffer(void *dst, uint32_t count, uint32_t offset) +{ + offset_ = offset; + ParseBuffer(dst, count); +} + void BinaryBufferParser::ParseBuffer(uint8_t *dst, uint32_t count, uint8_t *src) { if (src >= buffer_ && src + count <= buffer_ + length_) { diff --git a/ecmascript/compiler/aot_file/binary_buffer_parser.h b/ecmascript/compiler/aot_file/binary_buffer_parser.h index 11f3c620c3..1ebe900e3e 100644 --- a/ecmascript/compiler/aot_file/binary_buffer_parser.h +++ b/ecmascript/compiler/aot_file/binary_buffer_parser.h @@ -23,7 +23,12 @@ public: BinaryBufferParser(uint8_t *buffer, uint32_t length) : buffer_(buffer), length_(length) {} ~BinaryBufferParser() = default; void ParseBuffer(void *dst, uint32_t count); + void ParseBuffer(void *dst, uint32_t count, uint32_t offset); void ParseBuffer(uint8_t *dst, uint32_t count, uint8_t *src); + uint8_t *GetAddr() const + { + return buffer_; + } private: uint8_t *buffer_ {nullptr}; diff --git a/ecmascript/compiler/aot_file/elf_builder.cpp b/ecmascript/compiler/aot_file/elf_builder.cpp index 354a3f6619..8a5e180752 100644 --- a/ecmascript/compiler/aot_file/elf_builder.cpp +++ b/ecmascript/compiler/aot_file/elf_builder.cpp @@ -21,48 +21,20 @@ namespace panda::ecmascript { void ElfBuilder::ModifyStrTabSection() { - bool existedStrTab = false; - uint64_t strTabAddr = 0; - uint32_t strTabSize = 0; - std::vector sectionNames; - std::map> §ions = sectionDes_.GetSectionsInfo(); - // modify strtab - for (auto &s : sections) { - if (s.first == ElfSecName::STRTAB) { - existedStrTab = true; - strTabAddr = s.second.first; - strTabSize = s.second.second; - break; - } - } - - for (auto &s : sections) { - ElfSection section = ElfSection(s.first); - if (!section.ShouldDumpToAOTFile()) { - continue; - } - auto str = sectionDes_.GetSecName(s.first); - llvm::ELF::Elf64_Word id = FindShName(str, strTabAddr, strTabSize); - if (id == static_cast(-1)) { - sectionNames.emplace_back(str); - } - } - uint32_t size = 0; - if (existedStrTab) { - size += strTabSize; - } - for (auto &str: sectionNames) { + std::map> §ions = des_[0].GetSectionsInfo(); + + uint32_t size = 1; + for (auto &s : sections_) { + std::string str = ModuleSectionDes::GetSecName(s); size = size + str.size() + 1; } + strTabPtr_ = std::make_unique(size); char *dst = strTabPtr_.get(); - if (strTabSize > 0) { - if ((memcpy_s(dst, size, reinterpret_cast(strTabAddr), strTabSize)) != EOK) { - UNREACHABLE(); - } - } - uint32_t i = strTabSize; - for (auto &str: sectionNames) { + dst[0] = 0x0; + uint32_t i = 1; + for (auto &s: sections_) { + std::string str = ModuleSectionDes::GetSecName(s); uint32_t copySize = str.size(); if (copySize == 0) { UNREACHABLE(); @@ -73,13 +45,10 @@ void ElfBuilder::ModifyStrTabSection() dst[i + copySize] = 0x0; i = i + copySize + 1; } - - if (existedStrTab) { + if (sections.find(ElfSecName::STRTAB) != sections.end()) { sections.erase(ElfSecName::STRTAB); } sections[ElfSecName::STRTAB] = std::make_pair(reinterpret_cast(strTabPtr_.get()), size); - [[maybe_unused]] uint32_t symtabSize = sections[ElfSecName::SYMTAB].second; - ASSERT(symtabSize % sizeof(llvm::ELF::Elf64_Sym) == 0); if (enableSecDump_) { DumpSection(); } @@ -87,7 +56,7 @@ void ElfBuilder::ModifyStrTabSection() void ElfBuilder::DumpSection() const { - const std::map> §ions = sectionDes_.GetSectionsInfo(); + const std::map> §ions = GetCurrentSecInfo(); // dump for (auto &s : sections) { ElfSection section = ElfSection(s.first); @@ -101,31 +70,35 @@ void ElfBuilder::DumpSection() const void ElfBuilder::AddArkStackMapSection() { - // add arkstackmap - std::map> §ions = sectionDes_.GetSectionsInfo(); - std::shared_ptr ptr = sectionDes_.GetArkStackMapSharePtr(); - uint64_t arkStackMapAddr = reinterpret_cast(ptr.get()); - uint32_t arkStackMapSize = sectionDes_.GetArkStackMapSize(); - if (arkStackMapSize > 0) { - sections[ElfSecName::ARK_STACKMAP] = std::pair(arkStackMapAddr, arkStackMapSize); + for (auto &des : des_) { + std::map> §ions = des.GetSectionsInfo(); + std::shared_ptr ptr = des.GetArkStackMapSharePtr(); + uint64_t arkStackMapAddr = reinterpret_cast(ptr.get()); + uint32_t arkStackMapSize = des.GetArkStackMapSize(); + if (arkStackMapSize > 0) { + sections[ElfSecName::ARK_STACKMAP] = std::pair(arkStackMapAddr, arkStackMapSize); + } } } -ElfBuilder::ElfBuilder(ModuleSectionDes sectionDes): sectionDes_(sectionDes) +ElfBuilder::ElfBuilder(const std::vector &des, + const std::vector §ions): des_(des), sections_(sections) { + ASSERT(des_.size() == AOT_MODULE_NUM || des_.size() == ASMSTUB_MODULE_NUM); AddArkStackMapSection(); ModifyStrTabSection(); sectionToAlign_ = { - {ElfSecName::RODATA, 8}, - {ElfSecName::RODATA_CST4, 8}, - {ElfSecName::RODATA_CST8, 8}, - {ElfSecName::RODATA_CST16, 8}, - {ElfSecName::RODATA_CST32, 8}, - {ElfSecName::TEXT, 16}, + {ElfSecName::RODATA, TEXT_SEC_ALIGN}, + {ElfSecName::RODATA_CST4, TEXT_SEC_ALIGN}, + {ElfSecName::RODATA_CST8, TEXT_SEC_ALIGN}, + {ElfSecName::RODATA_CST16, TEXT_SEC_ALIGN}, + {ElfSecName::RODATA_CST32, TEXT_SEC_ALIGN}, + {ElfSecName::TEXT, TEXT_SEC_ALIGN}, {ElfSecName::STRTAB, 1}, - {ElfSecName::SYMTAB, 8}, - {ElfSecName::ARK_STACKMAP, 8}, - {ElfSecName::ARK_FUNCENTRY, 8}, + {ElfSecName::ARK_STACKMAP, DATA_SEC_ALIGN}, + {ElfSecName::ARK_FUNCENTRY, DATA_SEC_ALIGN}, + {ElfSecName::ARK_ASMSTUB, DATA_SEC_ALIGN}, + {ElfSecName::ARK_MODULEINFO, DATA_SEC_ALIGN}, }; sectionToSegment_ = { @@ -136,15 +109,31 @@ ElfBuilder::ElfBuilder(ModuleSectionDes sectionDes): sectionDes_(sectionDes) {ElfSecName::RODATA_CST32, ElfSecName::TEXT}, {ElfSecName::TEXT, ElfSecName::TEXT}, {ElfSecName::STRTAB, ElfSecName::DATA}, - {ElfSecName::SYMTAB, ElfSecName::DATA}, {ElfSecName::ARK_STACKMAP, ElfSecName::DATA}, {ElfSecName::ARK_FUNCENTRY, ElfSecName::DATA}, + {ElfSecName::ARK_ASMSTUB, ElfSecName::TEXT}, + {ElfSecName::ARK_MODULEINFO, ElfSecName::DATA}, }; segmentToFlag_ = { {ElfSecName::TEXT, llvm::ELF::PF_X | llvm::ELF::PF_R}, {ElfSecName::DATA, llvm::ELF::PF_R}, }; + + RemoveNotNeedSection(); +} + +void ElfBuilder::RemoveNotNeedSection() +{ + const std::map> §ions = GetCurrentSecInfo(); + for (size_t i = 0; i < sections_.size();) { + if (sections.find(sections_[i]) == sections.end()) { + auto it = sections_.begin() + i; + sections_.erase(it); + continue; + } + i++; + } } ElfBuilder::~ElfBuilder() @@ -152,49 +141,22 @@ ElfBuilder::~ElfBuilder() strTabPtr_ = nullptr; } -llvm::ELF::Elf64_Half ElfBuilder::GetShStrNdx(std::map>& sections) const +uint32_t ElfBuilder::GetShIndex(ElfSecName section) const { - llvm::ELF::Elf64_Half shstrndx = 1; // skip null section - for (auto &s : sections) { - ElfSection section = ElfSection(s.first); - if (!section.ShouldDumpToAOTFile()) { - continue; + std::set secSet(sections_.begin(), sections_.end()); + uint32_t idx = 1; + for (ElfSecName sec : secSet) { + if (sec == section) { + return idx; } - if (s.first == ElfSecName::STRTAB) { - return shstrndx; - } - shstrndx++; + idx++; } - UNREACHABLE(); -} - -llvm::ELF::Elf64_Half ElfBuilder::GetSecSize() const -{ - llvm::ELF::Elf64_Half secsSize = 0; - const std::map> §ions = sectionDes_.GetSectionsInfo(); - for (auto &s : sections) { - ElfSection section = ElfSection(s.first); - if (!section.ShouldDumpToAOTFile()) { - continue; - } - uint32_t curSecSize = sectionDes_.GetSecSize(s.first); - secsSize += curSecSize; - } - return secsSize; + return -1; } int ElfBuilder::GetSecNum() const { - int secNum = 0; - const std::map> §ions = sectionDes_.GetSectionsInfo(); - for (auto &s : sections) { - ElfSection section = ElfSection(s.first); - if (!section.ShouldDumpToAOTFile()) { - continue; - } - ++secNum; - } - return secNum; + return sections_.size(); } /* @@ -203,14 +165,14 @@ ELF Header: Magic: 7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00 Class: ELF64 Data: 2's complement, little endian - Version: 1 + Version: 1 (current) OS/ABI: UNIX - System V ABI Version: 0 Type: DYN (Shared object file) Machine: Advanced Micro Devices X86-64 - Version: 0x2 + Version: 0x4000001 Entry point address: 0x0 - Start of program headers: 20480 (bytes into file) + Start of program headers: 16384 (bytes into file) Start of section headers: 64 (bytes into file) Flags: 0x0 Size of this header: 64 (bytes) @@ -219,7 +181,6 @@ ELF Header: Size of section headers: 64 (bytes) Number of section headers: 7 Section header string table index: 3 -There are 7 section headers, starting at offset 0x40: */ void ElfBuilder::PackELFHeader(llvm::ELF::Elf64_Ehdr &header, uint32_t version, Triple triple) { @@ -250,7 +211,6 @@ void ElfBuilder::PackELFHeader(llvm::ELF::Elf64_Ehdr &header, uint32_t version, break; } header.e_version = version; - std::map> §ions = sectionDes_.GetSectionsInfo(); // start of section headers header.e_shoff = sizeof(llvm::ELF::Elf64_Ehdr); // size of ehdr @@ -260,7 +220,9 @@ void ElfBuilder::PackELFHeader(llvm::ELF::Elf64_Ehdr &header, uint32_t version, // number of section headers header.e_shnum = GetSecNum() + 1; // 1: skip null section and ark stackmap // section header string table index - header.e_shstrndx = GetShStrNdx(sections); + header.e_shstrndx = static_cast(GetShIndex(ElfSecName::STRTAB)); + // section header stub sec info index + header.e_flags = static_cast(GetShIndex(ElfSecName::ARK_MODULEINFO)); // phr header.e_phentsize = sizeof(llvm::ELF::Elf64_Phdr); header.e_phnum = GetSegmentNum(); @@ -268,7 +230,7 @@ void ElfBuilder::PackELFHeader(llvm::ELF::Elf64_Ehdr &header, uint32_t version, int ElfBuilder::GetSegmentNum() const { - const std::map> §ions = sectionDes_.GetSectionsInfo(); + const std::map> §ions = GetCurrentSecInfo(); std::set segments; for (auto &s: sections) { ElfSection section = ElfSection(s.first); @@ -286,7 +248,7 @@ int ElfBuilder::GetSegmentNum() const ElfSecName ElfBuilder::FindLastSection(ElfSecName segment) const { ElfSecName ans = ElfSecName::NONE; - const std::map> §ions = sectionDes_.GetSectionsInfo(); + const std::map> §ions = GetCurrentSecInfo(); for (auto &s: sections) { ElfSection section = ElfSection(s.first); if (!section.ShouldDumpToAOTFile()) { @@ -306,7 +268,7 @@ ElfSecName ElfBuilder::FindLastSection(ElfSecName segment) const llvm::ELF::Elf64_Word ElfBuilder::FindShName(std::string name, uintptr_t strTabPtr, int strTabSize) { llvm::ELF::Elf64_Word ans = -1; - int len = static_cast(name.size()); + int len = name.size(); if (strTabSize < len + 1) { return ans; } @@ -322,12 +284,12 @@ llvm::ELF::Elf64_Word ElfBuilder::FindShName(std::string name, uintptr_t strTabP std::pair ElfBuilder::FindStrTab() const { - const std::map> §ions = sectionDes_.GetSectionsInfo(); + const std::map> §ions = GetCurrentSecInfo(); uint64_t strTabAddr = 0; uint32_t strTabSize = 0; for (auto &s: sections) { - uint32_t curSecSize = sectionDes_.GetSecSize(s.first); - uint64_t curSecAddr = sectionDes_.GetSecAddr(s.first); + uint32_t curSecSize = des_[0].GetSecSize(s.first); + uint64_t curSecAddr = des_[0].GetSecAddr(s.first); if (s.first == ElfSecName::STRTAB) { strTabSize = curSecSize; strTabAddr = curSecAddr; @@ -337,78 +299,142 @@ std::pair ElfBuilder::FindStrTab() const return std::make_pair(strTabAddr, strTabSize); } -/* -section layout as follows: -Section Headers: - [Nr] Name Type Address Off Size ES Flg Lk Inf Al - [ 0] NULL 0000000000000000 000000 000000 00 0 0 0 - [ 1] .rodata.cst8 PROGBITS 0000000000001000 001000 000020 00 AM 0 0 8 - [ 2] .text PROGBITS 0000000000001020 001020 001130 00 AX 0 0 16 - [ 3] .strtab STRTAB 0000000000003000 003000 0001a5 00 A 0 0 1 - [ 4] .symtab SYMTAB 00000000000031a8 0031a8 0001c8 18 A 1 0 8 - [ 5] .ark_funcentry PROGBITS 0000000000003370 003370 0006c0 00 A 0 0 8 - [ 6] .ark_stackmaps PROGBITS 0000000000003a30 003a30 0010f5 00 A 0 0 8 -*/ -void ElfBuilder::PackELFSections(std::ofstream &file) +void ElfBuilder::AllocateShdr(std::unique_ptr &shdr, const uint32_t &secNum) { - std::map> §ions = sectionDes_.GetSectionsInfo(); - uint32_t secNum = sections.size() + 1; // 1 : section id = 0 is null section - std::unique_ptr shdr = std::make_unique(secNum); - if (memset_s(reinterpret_cast(&shdr[0]), sizeof(llvm::ELF::Elf64_Shdr), 0, sizeof(llvm::ELF::Elf64_Shdr)) != EOK) { + shdr = std::make_unique(secNum); + if (memset_s(reinterpret_cast(&shdr[0]), sizeof(llvm::ELF::Elf64_Shdr), + 0, sizeof(llvm::ELF::Elf64_Shdr)) != EOK) { UNREACHABLE(); } +} +llvm::ELF::Elf64_Off ElfBuilder::ComputeEndAddrOfShdr(const uint32_t &secNum) const +{ llvm::ELF::Elf64_Off curSecOffset = sizeof(llvm::ELF::Elf64_Ehdr) + secNum * sizeof(llvm::ELF::Elf64_Shdr); curSecOffset = AlignUp(curSecOffset, PageSize()); // not pagesize align will cause performance degradation + return curSecOffset; +} + +ElfSecName ElfBuilder::GetSegmentName(const ElfSecName &secName) const +{ + auto it = sectionToSegment_.find(secName); + ASSERT(it != sectionToSegment_.end()); + ElfSecName segName = it->second; + return segName; +} + +void ElfBuilder::MergeTextSections(std::ofstream &file, + std::vector &moduleInfo, + llvm::ELF::Elf64_Off &curSecOffset) +{ + for (size_t i = 0; i < des_.size(); ++i) { + ModuleSectionDes &des = des_[i]; + ModuleSectionDes::ModuleRegionInfo &curInfo = moduleInfo[i]; + uint32_t curSecSize = des.GetSecSize(ElfSecName::TEXT); + uint64_t curSecAddr = des.GetSecAddr(ElfSecName::TEXT); + curSecOffset = AlignUp(curSecOffset, TEXT_SEC_ALIGN); + file.seekp(curSecOffset); + auto curModuleSec = des.GetSectionsInfo(); + if (curModuleSec.find(ElfSecName::RODATA_CST8) != curModuleSec.end()) { + uint32_t rodataSize = des.GetSecSize(ElfSecName::RODATA_CST8); + uint64_t rodataAddr = des.GetSecAddr(ElfSecName::RODATA_CST8); + file.write(reinterpret_cast(rodataAddr), rodataSize); + curInfo.rodataSize = rodataSize; + curSecOffset += rodataSize; + } + curInfo.textSize = curSecSize; + file.write(reinterpret_cast(curSecAddr), curSecSize); + curSecOffset += curSecSize; + } +} + +void ElfBuilder::MergeArkStackMapSections(std::ofstream &file, + std::vector &moduleInfo, + llvm::ELF::Elf64_Off &curSecOffset) +{ + for (size_t i = 0; i < des_.size(); ++i) { + ModuleSectionDes &des = des_[i]; + ModuleSectionDes::ModuleRegionInfo &curInfo = moduleInfo[i]; + uint32_t curSecSize = des.GetSecSize(ElfSecName::ARK_STACKMAP); + uint64_t curSecAddr = des.GetSecAddr(ElfSecName::ARK_STACKMAP); + uint32_t index = des.GetStartIndex(); + uint32_t cnt = des.GetFuncCount(); + curInfo.startIndex = index; + curInfo.funcCount = cnt; + curInfo.stackMapSize = curSecSize; + file.write(reinterpret_cast(curSecAddr), curSecSize); + curSecOffset += curSecSize; + } +} + +/* +section layout as follows: +There are 6 section headers, starting at offset 0x40: + +Section Headers: + [Nr] Name Type Address Offset Size EntSize Flags Link Info Align + [ 0] NULL 0000000000000000 00000000 0000000000000000 0000000000000000 0 0 0 + [ 1] .rodata.cst8 PROGBITS 0000000000001000 00001000 0000000000000020 0000000000000000 AM 0 0 8 + [ 2] .text PROGBITS 0000000000001020 00001020 000000000000112a 0000000000000000 AX 0 0 16 + [ 3] .strtab STRTAB 0000000000003000 00003000 000000000000003a 0000000000000000 A 0 0 1 + [ 4] .ark_funcentry PROGBITS 0000000000003040 00003040 00000000000006c0 0000000000000000 A 0 0 8 + [ 5] .ark_stackmaps PROGBITS 0000000000003700 00003700 0000000000000754 0000000000000000 A 0 0 8 +Key to Flags: + W (write), A (alloc), X (execute), M (merge), S (strings), I (info), + L (link order), O (extra OS processing required), G (group), T (TLS), + C (compressed), x (unknown), o (OS specific), E (exclude), + D (mbind), l (large), p (processor specific) +*/ +void ElfBuilder::PackAnELFSections(std::ofstream &file) +{ + ASSERT(des_.size() == AOT_MODULE_NUM); + const std::map> §ions = GetCurrentSecInfo(); + uint32_t secNum = sections.size() + 1; // 1 : section id = 0 is null section + std::unique_ptr shdr; + AllocateShdr(shdr, secNum); + + llvm::ELF::Elf64_Off curSecOffset = ComputeEndAddrOfShdr(secNum); file.seekp(curSecOffset); int i = 1; // 1: skip null section auto strTab = FindStrTab(); - for (auto &s: sections) { - ElfSection section = ElfSection(s.first); + for (auto const &[secName, secInfo] : sections) { + auto &curShdr = shdr[i]; + ElfSection section = ElfSection(secName); if (!section.ShouldDumpToAOTFile()) { continue; } - shdr[i].sh_addralign = sectionToAlign_[s.first]; - if (curSecOffset % shdr[i].sh_addralign != 0) { - curSecOffset = AlignUp(curSecOffset, shdr[i].sh_addralign); - file.seekp(curSecOffset); - } - auto it = sectionToSegment_.find(s.first); - ASSERT(it != sectionToSegment_.end()); - ElfSecName segName = it->second; + curShdr.sh_addralign = sectionToAlign_[secName]; + curSecOffset = AlignUp(curSecOffset, curShdr.sh_addralign); + file.seekp(curSecOffset); + ElfSecName segName = GetSegmentName(secName); segments_.insert(segName); - uint32_t curSecSize = sectionDes_.GetSecSize(s.first); - uint64_t curSecAddr = sectionDes_.GetSecAddr(s.first); - std::string secName = sectionDes_.GetSecName(s.first); - // text section address needs 16 bytes alignment - if ((ElfSecName::RODATA <= s.first && s.first <= ElfSecName::RODATA_CST8) || s.first == ElfSecName::TEXT) { - curSecOffset = AlignUp(curSecOffset, TEXT_SEC_ALIGN); - file.seekp(curSecOffset); - } - sectionToFileOffset_[s.first] = static_cast(file.tellp()); + uint32_t curSecSize = GetCurrentDes().GetSecSize(secName); + uint64_t curSecAddr = GetCurrentDes().GetSecAddr(secName); + std::string secNameStr = ModuleSectionDes::GetSecName(secName); + sectionToFileOffset_[secName] = static_cast(file.tellp()); file.write(reinterpret_cast(curSecAddr), curSecSize); - llvm::ELF::Elf64_Word shName = FindShName(secName, strTab.first, strTab.second); + llvm::ELF::Elf64_Word shName = FindShName(secNameStr, strTab.first, strTab.second); ASSERT(shName != static_cast(-1)); - shdr[i].sh_name = shName; - shdr[i].sh_type = section.Type(); - shdr[i].sh_flags = section.Flag(); - shdr[i].sh_addr = curSecOffset; - shdr[i].sh_offset = curSecOffset; + curShdr.sh_name = shName; + curShdr.sh_type = section.Type(); + curShdr.sh_flags = section.Flag(); + curShdr.sh_addr = curSecOffset; + curShdr.sh_offset = curSecOffset; LOG_COMPILER(DEBUG) << "curSecOffset: 0x" << std::hex << curSecOffset << " curSecSize:0x" << curSecSize; curSecOffset += curSecSize; ElfSecName lastSecName = FindLastSection(segName); - if (s.first == lastSecName) { + if (secName == lastSecName) { curSecOffset = AlignUp(curSecOffset, PageSize()); file.seekp(curSecOffset); } - shdr[i].sh_size = curSecSize; - shdr[i].sh_link = section.Link(); - shdr[i].sh_info = 0; - shdr[i].sh_entsize = section.Entsize(); - sectionToShdr_[s.first] = shdr[i]; - LOG_COMPILER(DEBUG) << " shdr[i].sh_entsize " << std::hex << shdr[i].sh_entsize << std::endl; + curShdr.sh_size = curSecSize; + curShdr.sh_link = section.Link(); + curShdr.sh_info = 0; + curShdr.sh_entsize = section.Entsize(); + sectionToShdr_[secName] = curShdr; + LOG_COMPILER(DEBUG) << " shdr[i].sh_entsize " << std::hex << curShdr.sh_entsize << std::endl; ++i; } uint32_t secEnd = static_cast(file.tellp()); @@ -417,6 +443,117 @@ void ElfBuilder::PackELFSections(std::ofstream &file) file.seekp(secEnd); } +/* +section layout as follows: +There are 7 section headers, starting at offset 0x40: + +Section Headers: + [Nr] Name Type Address Offset Size EntSize Flags Link Info Align + [ 0] NULL 0000000000000000 00000000 0000000000000000 0000000000000000 0 0 0 + [ 1] .text PROGBITS 0000000000001000 00001000 000000000008148e 0000000000000000 AX 0 0 16 + [ 2] .ark_asmstub PROGBITS 0000000000082490 00082490 0000000000002dc0 0000000000000000 AX 0 0 8 + [ 3] .strtab STRTAB 0000000000086000 00086000 0000000000000048 0000000000000000 A 0 0 1 + [ 4] .ark_funcentry PROGBITS 0000000000086048 00086048 0000000000023ca0 0000000000000000 A 0 0 8 + [ 5] .ark_stackmaps PROGBITS 00000000000a9ce8 000a9ce8 00000000000119cc 0000000000000000 A 0 0 8 + [ 6] .ark_moduleinfo PROGBITS 00000000000bb6b8 000bb6b8 000000000000003c 0000000000000000 A 0 0 8 +Key to Flags: + W (write), A (alloc), X (execute), M (merge), S (strings), I (info), + L (link order), O (extra OS processing required), G (group), T (TLS), + C (compressed), x (unknown), o (OS specific), E (exclude), + D (mbind), l (large), p (processor specific) +*/ +void ElfBuilder::PackStubELFSections(std::ofstream &file) +{ + ASSERT(des_.size() == ASMSTUB_MODULE_NUM); + const std::map> §ions = GetCurrentSecInfo(); + uint32_t secNum = sections.size() + 1; // 1 : section id = 0 is null section + std::unique_ptr shdr; + AllocateShdr(shdr, secNum); + std::vector moduleInfo(ASMSTUB_MODULE_NUM); + llvm::ELF::Elf64_Off curSecOffset = ComputeEndAddrOfShdr(secNum); + file.seekp(curSecOffset); + + int i = 1; // 1: skip null section + auto strTab = FindStrTab(); + + for (auto const &[secName, secInfo] : sections) { + auto &curShdr = shdr[i]; + ElfSection section = ElfSection(secName); + if (!section.ShouldDumpToStubFile()) { + continue; + } + curShdr.sh_addralign = sectionToAlign_[secName]; + curSecOffset = AlignUp(curSecOffset, curShdr.sh_addralign); + file.seekp(curSecOffset); + ElfSecName segName = GetSegmentName(secName); + segments_.insert(segName); + std::string secNameStr = ModuleSectionDes::GetSecName(secName); + // text section address needs 16 bytes alignment + if (secName == ElfSecName::TEXT) { + curSecOffset = AlignUp(curSecOffset, TEXT_SEC_ALIGN); + file.seekp(curSecOffset); + } + llvm::ELF::Elf64_Word shName = FindShName(secNameStr, strTab.first, strTab.second); + ASSERT(shName != static_cast(-1)); + curShdr.sh_name = shName; + curShdr.sh_type = section.Type(); + curShdr.sh_flags = section.Flag(); + curShdr.sh_addr = curSecOffset; + curShdr.sh_offset = curSecOffset; + sectionToFileOffset_[secName] = file.tellp(); + switch (secName) { + case ElfSecName::ARK_MODULEINFO: { + uint32_t curSecSize = sizeof(ModuleSectionDes::ModuleRegionInfo) * moduleInfo.size(); + file.write(reinterpret_cast(moduleInfo.data()), curSecSize); + curSecOffset += curSecSize; + curShdr.sh_size = curSecSize; + break; + } + case ElfSecName::TEXT: { + uint32_t curSize = curSecOffset; + MergeTextSections(file, moduleInfo, curSecOffset); + curShdr.sh_size = curSecOffset - curSize; + break; + } + case ElfSecName::ARK_STACKMAP: { + uint32_t curSize = curSecOffset; + MergeArkStackMapSections(file, moduleInfo, curSecOffset); + curShdr.sh_size = curSecOffset - curSize; + break; + } + case ElfSecName::STRTAB: + case ElfSecName::ARK_FUNCENTRY: + case ElfSecName::ARK_ASMSTUB: { + uint32_t curSecSize = GetCurrentDes().GetSecSize(secName); + uint64_t curSecAddr = GetCurrentDes().GetSecAddr(secName); + file.write(reinterpret_cast(curSecAddr), curSecSize); + curSecOffset += curSecSize; + curShdr.sh_size = curSecSize; + break; + } + default: { + LOG_ECMA(FATAL) << "this section should not dump to stub file"; + break; + } + } + ElfSecName lastSecName = FindLastSection(segName); + if (secName == lastSecName) { + curSecOffset = AlignUp(curSecOffset, PageSize()); + file.seekp(curSecOffset); + } + curShdr.sh_link = section.Link(); + curShdr.sh_info = 0; + curShdr.sh_entsize = section.Entsize(); + sectionToShdr_[secName] = curShdr; + LOG_COMPILER(DEBUG) << " shdr[i].sh_entsize " << std::hex << curShdr.sh_entsize << std::endl; + ++i; + } + uint32_t secEnd = file.tellp(); + file.seekp(sizeof(llvm::ELF::Elf64_Ehdr)); + file.write(reinterpret_cast(shdr.get()), secNum * sizeof(llvm::ELF::Elf64_Shdr)); + file.seekp(secEnd); +} + unsigned ElfBuilder::GetPFlag(ElfSecName segment) const { return segmentToFlag_.at(segment); @@ -424,16 +561,33 @@ unsigned ElfBuilder::GetPFlag(ElfSecName segment) const /* segment layout as follows: +An Elf file +Entry point 0x0 +There are 2 program headers, starting at offset 16384 + Program Headers: - Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align - LOAD 0x001000 0x0000000000001000 0x0000000000001000 0x001150 0x002000 R E 0x1000 - LOAD 0x003000 0x0000000000003000 0x0000000000003000 0x001b25 0x002000 R 0x1000 + Type Offset VirtAddr PhysAddr FileSiz MemSiz Flags Align + LOAD 0x0000000000001000 0x0000000000001000 0x0000000000001000 0x000000000000114a 0x0000000000002000 R E 0x1000 + LOAD 0x0000000000003000 0x0000000000003000 0x0000000000003000 0x0000000000000e54 0x0000000000001000 R 0x1000 Section to Segment mapping: Segment Sections... 00 .rodata.cst8 .text - 01 .strtab .symtab .ark_funcentry .ark_stackmaps - None + 01 .strtab .ark_funcentry .ark_stackmaps +------------------------------------------------------------------------------------------------------------------------------ +Stub Elf file +Entry point 0x0 +There are 2 program headers, starting at offset 770048 + +Program Headers: + Type Offset VirtAddr PhysAddr FileSiz MemSiz Flags Align + LOAD 0x0000000000000000 0x0000000000000000 0x0000000000000000 0x0000000000085250 0x0000000000086000 R E 0x1000 + LOAD 0x0000000000086000 0x0000000000086000 0x0000000000086000 0x00000000000356f4 0x0000000000036000 R 0x1000 + + Section to Segment mapping: + Segment Sections... + 00 .text .ark_asmstub + 01 .strtab .ark_funcentry .ark_stackmaps .ark_moduleinfo */ void ElfBuilder::PackELFSegment(std::ofstream &file) { @@ -450,7 +604,7 @@ void ElfBuilder::PackELFSegment(std::ofstream &file) std::map segmentToMaxAddress; std::set segments; // SecName -> addr & size - std::map> §ions = sectionDes_.GetSectionsInfo(); + const std::map> §ions = GetCurrentSecInfo(); llvm::ELF::Elf64_Off offset = e_phoff; for (auto &s: sections) { ElfSection section = ElfSection(s.first); diff --git a/ecmascript/compiler/aot_file/elf_builder.h b/ecmascript/compiler/aot_file/elf_builder.h index 6860d43d2e..b3068f04ed 100644 --- a/ecmascript/compiler/aot_file/elf_builder.h +++ b/ecmascript/compiler/aot_file/elf_builder.h @@ -30,38 +30,58 @@ class ModuleSectionDes; class ElfBuilder { public: - ElfBuilder(ModuleSectionDes sectionDes); + ElfBuilder(const std::vector &des, const std::vector §ions); ~ElfBuilder(); void PackELFHeader(llvm::ELF::Elf64_Ehdr &header, uint32_t version, Triple triple); - void PackELFSections(std::ofstream &elfFile); + void PackAnELFSections(std::ofstream &elfFile); + void PackStubELFSections(std::ofstream &elfFile); void PackELFSegment(std::ofstream &elfFile); + void MergeTextSections(std::ofstream &elfFile, + std::vector &moduleInfo, llvm::ELF::Elf64_Off &curSecOffset); + void MergeArkStackMapSections(std::ofstream &elfFile, + std::vector &moduleInfo, llvm::ELF::Elf64_Off &curSecOffset); static llvm::ELF::Elf64_Word FindShName(std::string name, uintptr_t strTabPtr, int strTabSize); + std::map> GetCurrentSecInfo() const + { + return des_[0].GetSectionsInfo(); + } + ModuleSectionDes GetCurrentDes() const + { + return des_[0]; + } void SetEnableSecDump(bool flag) { enableSecDump_ = flag; } private: - llvm::ELF::Elf64_Half GetShStrNdx(std::map> §ions) const; - llvm::ELF::Elf64_Half GetSecSize() const; + uint32_t GetShIndex(ElfSecName section) const; ElfSecName FindLastSection(ElfSecName segment) const; int GetSegmentNum() const; int GetSecNum() const; unsigned GetPFlag(ElfSecName segment) const; + ElfSecName GetSegmentName(const ElfSecName &secName) const; std::pair FindStrTab() const; + void AllocateShdr(std::unique_ptr &shdr, const uint32_t &secNum); + llvm::ELF::Elf64_Off ComputeEndAddrOfShdr(const uint32_t &secNum) const; bool SupportELF(); void AddArkStackMapSection(); void DumpSection() const; void ModifyStrTabSection(); + void RemoveNotNeedSection(); + static constexpr uint32_t DATA_SEC_ALIGN = 8; static constexpr uint32_t TEXT_SEC_ALIGN = 16; - ModuleSectionDes sectionDes_; + static constexpr uint32_t ASMSTUB_MODULE_NUM = 3; + static constexpr uint32_t AOT_MODULE_NUM = 1; + std::vector des_ {}; std::unique_ptr strTabPtr_ {nullptr}; std::map sectionToShdr_; std::map sectionToAlign_; std::map sectionToSegment_; std::map sectionToFileOffset_; std::map segmentToFlag_; + std::vector sections_ {}; std::set segments_; bool enableSecDump_ {false}; }; diff --git a/ecmascript/compiler/aot_file/elf_reader.cpp b/ecmascript/compiler/aot_file/elf_reader.cpp index 6836956e5b..75ec9df7a9 100644 --- a/ecmascript/compiler/aot_file/elf_reader.cpp +++ b/ecmascript/compiler/aot_file/elf_reader.cpp @@ -43,6 +43,7 @@ void ElfReader::ParseELFSections(ModuleSectionDes &des, std::vector llvm::ELF::Elf64_Ehdr *ehdr = reinterpret_cast(fileMapMem_.GetOriginAddr()); char *addr = reinterpret_cast(ehdr); llvm::ELF::Elf64_Shdr *shdr = reinterpret_cast(addr + ehdr->e_shoff); + ASSERT(ehdr->e_shstrndx != static_cast(-1)); llvm::ELF::Elf64_Shdr strdr = shdr[ehdr->e_shstrndx]; for (size_t j = 0; j < secs.size(); ++j) { int secId = -1; @@ -71,8 +72,146 @@ void ElfReader::ParseELFSections(ModuleSectionDes &des, std::vector des.SetArkStackMapPtr(reinterpret_cast(secAddr)); des.SetArkStackMapSize(secSize); } else { - des.SetSecAddr(secAddr, sec); - des.SetSecSize(secSize, sec); + des.SetSecAddrAndSize(sec, secAddr, secSize); + } + } +} + +ModuleSectionDes::ModuleRegionInfo ElfReader::GetCurModuleInfo(uint32_t i, llvm::ELF::Elf64_Off offset) +{ + uint64_t codeAddress = reinterpret_cast(fileMapMem_.GetOriginAddr()); + return *(reinterpret_cast + (codeAddress + offset + i * sizeof(ModuleSectionDes::ModuleRegionInfo))); +} + +void ElfReader::ParseELFSections(std::vector &des, std::vector &secs) +{ + ASSERT(des.size() == ASMSTUB_MODULE_NUM); + llvm::ELF::Elf64_Ehdr *ehdr = reinterpret_cast(fileMapMem_.GetOriginAddr()); + char *addr = reinterpret_cast(ehdr); + llvm::ELF::Elf64_Shdr *shdrs = reinterpret_cast(addr + ehdr->e_shoff); + ASSERT(ehdr->e_shstrndx != static_cast(-1)); + llvm::ELF::Elf64_Shdr strdr = shdrs[ehdr->e_shstrndx]; + ASSERT(ehdr->e_flags != static_cast(-1)); + llvm::ELF::Elf64_Shdr moduledr = shdrs[ehdr->e_flags]; + [[maybe_unused]] size_t moduleInfoSize = moduledr.sh_size; + ASSERT(moduleInfoSize % sizeof(ModuleSectionDes::ModuleRegionInfo) == 0); + std::set secSet(secs.begin(), secs.end()); + for (ElfSecName sec : secSet) { + int secId = -1; + std::string sectionName = ModuleSectionDes::GetSecName(sec); + for (size_t i = 0; i < ehdr->e_shnum; ++i) { + llvm::ELF::Elf64_Word shName = shdrs[i].sh_name; + char *curShName = reinterpret_cast(addr) + shName + strdr.sh_offset; + if (sectionName.compare(curShName) == 0) { + secId = i; + break; + } + } + if (secId == -1) { + LOG_COMPILER(DEBUG) << "sectionName: " << sectionName << " not found in strtab"; + continue; + } + ASSERT(secId > 0 && secId < ehdr->e_shnum); + llvm::ELF::Elf64_Shdr secShdr = shdrs[secId]; + uintptr_t secAddr = reinterpret_cast(addr + secShdr.sh_offset); + uint32_t secSize = secShdr.sh_size; + switch (sec) { + case ElfSecName::TEXT: { + llvm::ELF::Elf64_Off secOffset = 0; + SeparateTextSections(des, secAddr, secOffset, moduledr.sh_offset); + ASSERT(static_cast(secOffset) == secSize); + break; + } + case ElfSecName::ARK_STACKMAP: { + llvm::ELF::Elf64_Off secOffset = 0; + SeparateArkStackMapSections(des, secAddr, secOffset, moduledr.sh_offset); + ASSERT(static_cast(secOffset) == secSize); + break; + } + case ElfSecName::STRTAB: + case ElfSecName::ARK_FUNCENTRY: + case ElfSecName::ARK_ASMSTUB: + case ElfSecName::ARK_MODULEINFO: { + if (sec == ElfSecName::ARK_FUNCENTRY) { + ASSERT((secSize > 0) && (secSize % sizeof(AOTFileInfo::FuncEntryDes) == 0)); + } + des[0].SetSecAddrAndSize(sec, secAddr, secSize); + break; + } + default: { + LOG_ECMA(FATAL) << "this section should not dump to stub file"; + break; + } + } + } +} + +void ElfReader::ParseELFSections(BinaryBufferParser &parser, std::vector &des, std::vector &secs) +{ + ASSERT(des.size() == ASMSTUB_MODULE_NUM); + uint64_t codeAddress = reinterpret_cast(stubsMem_.addr_); + llvm::ELF::Elf64_Ehdr ehdr; + parser.ParseBuffer(&ehdr, sizeof(ehdr), 0); + std::vector shdrs(ehdr.e_shnum); + parser.ParseBuffer(shdrs.data(), sizeof(llvm::ELF::Elf64_Shdr) * ehdr.e_shnum, ehdr.e_shoff); + + ASSERT(ehdr.e_shstrndx != static_cast(-1)); + llvm::ELF::Elf64_Shdr strdr = shdrs[ehdr.e_shstrndx]; + ASSERT(ehdr.e_flags != static_cast(-1)); + llvm::ELF::Elf64_Shdr moduledr = shdrs[ehdr.e_flags]; + [[maybe_unused]] size_t moduleInfoSize = moduledr.sh_size; + ASSERT(moduleInfoSize % sizeof(ModuleSectionDes::ModuleRegionInfo) == 0); + moduleInfo_.resize(ASMSTUB_MODULE_NUM); + parser.ParseBuffer(moduleInfo_.data(), sizeof(ModuleSectionDes::ModuleRegionInfo) * ASMSTUB_MODULE_NUM, moduledr.sh_offset); + std::set secSet(secs.begin(), secs.end()); + for (ElfSecName sec : secSet) { + int secId = -1; + std::string sectionName = ModuleSectionDes::GetSecName(sec); + for (size_t i = 0; i < ehdr.e_shnum; ++i) { + llvm::ELF::Elf64_Word shName = shdrs[i].sh_name; + char *curShName = reinterpret_cast(parser.GetAddr()) + shName + strdr.sh_offset; + if (sectionName.compare(curShName) == 0) { + secId = i; + break; + } + } + if (secId == -1) { + LOG_COMPILER(DEBUG) << "sectionName: " << sectionName << " not found in strtab"; + continue; + } + ASSERT(secId > 0 && secId < ehdr.e_shnum); + llvm::ELF::Elf64_Shdr secShdr = shdrs[secId]; + uint64_t secAddr = static_cast(codeAddress + secShdr.sh_offset); + uint32_t secSize = secShdr.sh_size; + switch (sec) { + case ElfSecName::TEXT: { + llvm::ELF::Elf64_Off secOffset = 0; + SeparateTextSections(parser, des, secAddr, secOffset, secShdr.sh_offset); + ASSERT(static_cast(secOffset) == secSize); + break; + } + case ElfSecName::ARK_STACKMAP: { + llvm::ELF::Elf64_Off secOffset = 0; + SeparateArkStackMapSections(parser, des, secAddr, secOffset, secShdr.sh_offset); + ASSERT(static_cast(secOffset) == secSize); + break; + } + case ElfSecName::STRTAB: + case ElfSecName::ARK_FUNCENTRY: + case ElfSecName::ARK_ASMSTUB: + case ElfSecName::ARK_MODULEINFO: { + if (sec == ElfSecName::ARK_FUNCENTRY) { + ASSERT((secSize > 0) && (secSize % sizeof(AOTFileInfo::FuncEntryDes) == 0)); + } + parser.ParseBuffer(reinterpret_cast(secAddr), secSize, secShdr.sh_offset); + des[0].SetSecAddrAndSize(sec, secAddr, secSize); + break; + } + default: { + LOG_ECMA(FATAL) << "this section should not dump to stub file"; + break; + } } } } @@ -106,4 +245,83 @@ bool ElfReader::ParseELFSegment() } return true; } + +void ElfReader::SeparateTextSections(std::vector &des, + const uintptr_t &secAddr, + llvm::ELF::Elf64_Off &secOffset, + const llvm::ELF::Elf64_Off &moduleInfoOffset) +{ + for (size_t i = 0; i < des.size(); ++i) { + auto moduleInfo = GetCurModuleInfo(i, moduleInfoOffset); + secOffset = AlignUp(secOffset, TEXT_SEC_ALIGN); + uint32_t rodataSize = moduleInfo.rodataSize; + if (rodataSize > 0) { + des[i].SetSecAddrAndSize(ElfSecName::RODATA_CST8, secAddr + secOffset, rodataSize); + secOffset += rodataSize; + } + uint32_t textSize = moduleInfo.textSize; + des[i].SetSecAddrAndSize(ElfSecName::TEXT, secAddr + secOffset, textSize); + secOffset += textSize; + } +} + +void ElfReader::SeparateArkStackMapSections(std::vector &des, + const uintptr_t &secAddr, + llvm::ELF::Elf64_Off &secOffset, + const llvm::ELF::Elf64_Off &moduleInfoOffset) +{ + for (size_t i = 0; i < des.size(); ++i) { + auto moduleInfo = GetCurModuleInfo(i, moduleInfoOffset); + uint32_t stackMapSize = moduleInfo.stackMapSize; + des[i].SetArkStackMapPtr(reinterpret_cast(secAddr + secOffset)); + des[i].SetArkStackMapSize(stackMapSize); + uint32_t index = moduleInfo.startIndex; + uint32_t cnt = moduleInfo.funcCount; + des[i].SetStartIndex(index); + des[i].SetFuncCount(cnt); + secOffset += stackMapSize; + } +} + +void ElfReader::SeparateTextSections(BinaryBufferParser &parser, + std::vector &des, + const uint64_t &secAddr, + llvm::ELF::Elf64_Off &secOffset, + const llvm::ELF::Elf64_Off &curShOffset) +{ + for (size_t i = 0; i < des.size(); ++i) { + auto moduleInfo = moduleInfo_[i]; + secOffset = AlignUp(secOffset, TEXT_SEC_ALIGN); + uint32_t rodataSize = moduleInfo.rodataSize; + if (rodataSize > 0) { + parser.ParseBuffer(reinterpret_cast(secAddr + secOffset), rodataSize, curShOffset + secOffset); + des[i].SetSecAddrAndSize(ElfSecName::RODATA_CST8, secAddr + secOffset, rodataSize); + secOffset += rodataSize; + } + uint32_t textSize = moduleInfo.textSize; + parser.ParseBuffer(reinterpret_cast(secAddr + secOffset), textSize, curShOffset + secOffset); + des[i].SetSecAddrAndSize(ElfSecName::TEXT, secAddr + secOffset, textSize); + secOffset += textSize; + } +} + +void ElfReader::SeparateArkStackMapSections(BinaryBufferParser &parser, + std::vector &des, + const uint64_t &secAddr, + llvm::ELF::Elf64_Off &secOffset, + const llvm::ELF::Elf64_Off &curShOffset) +{ + for (size_t i = 0; i < des.size(); ++i) { + auto moduleInfo = moduleInfo_[i]; + uint32_t stackMapSize = moduleInfo.stackMapSize; + parser.ParseBuffer(reinterpret_cast(secAddr + secOffset), stackMapSize, curShOffset + secOffset); + des[i].SetArkStackMapPtr(reinterpret_cast(secAddr + secOffset)); + des[i].SetArkStackMapSize(stackMapSize); + uint32_t index = moduleInfo.startIndex; + uint32_t cnt = moduleInfo.funcCount; + des[i].SetStartIndex(index); + des[i].SetFuncCount(cnt); + secOffset += stackMapSize; + } +} } // namespace panda::ecmascript \ No newline at end of file diff --git a/ecmascript/compiler/aot_file/elf_reader.h b/ecmascript/compiler/aot_file/elf_reader.h index a092bdbb7b..b6625dbb5f 100644 --- a/ecmascript/compiler/aot_file/elf_reader.h +++ b/ecmascript/compiler/aot_file/elf_reader.h @@ -27,14 +27,30 @@ class ModuleSectionDes; class ElfReader { public: - ElfReader(MemMap fileMapMem) : fileMapMem_(fileMapMem) {}; + ElfReader(const MemMap &fileMapMem) : fileMapMem_(fileMapMem) {}; + ElfReader(ExecutedMemoryAllocator::ExeMem &stubsMem) : stubsMem_(stubsMem) {}; ~ElfReader() = default; bool VerifyELFHeader(uint32_t version, bool strictMatch); void ParseELFSections(ModuleSectionDes &des, std::vector &secs); + void ParseELFSections(std::vector &des, std::vector &secs); + void ParseELFSections(BinaryBufferParser &parser, std::vector &des, std::vector &secs); bool ParseELFSegment(); + ModuleSectionDes::ModuleRegionInfo GetCurModuleInfo(uint32_t i, llvm::ELF::Elf64_Off offset); + void SeparateTextSections(std::vector &des, const uintptr_t &secAddr, + llvm::ELF::Elf64_Off &secOffset, const llvm::ELF::Elf64_Off &moduleInfoOffset); + void SeparateArkStackMapSections(std::vector &des, const uintptr_t &secAddr, + llvm::ELF::Elf64_Off &secOffset, const llvm::ELF::Elf64_Off &moduleInfoOffset); + void SeparateTextSections(BinaryBufferParser &parser, std::vector &des, + const uint64_t &secAddr, llvm::ELF::Elf64_Off &secOffset, const llvm::ELF::Elf64_Off &curShOffset); + void SeparateArkStackMapSections(BinaryBufferParser &parser, std::vector &des, + const uint64_t &secAddr, llvm::ELF::Elf64_Off &secOffset, const llvm::ELF::Elf64_Off &curShOffset); private: + static constexpr uint32_t TEXT_SEC_ALIGN = 16; + static constexpr uint32_t ASMSTUB_MODULE_NUM = 3; + ExecutedMemoryAllocator::ExeMem stubsMem_ {}; MemMap fileMapMem_ {}; + std::vector moduleInfo_; }; } // namespace panda::ecmascript #endif // ECMASCRIPT_COMPILER_AOT_FILE_ELF_READER_H \ No newline at end of file diff --git a/ecmascript/compiler/aot_file/module_section_des.cpp b/ecmascript/compiler/aot_file/module_section_des.cpp index c8eeabcc91..c5b9b47046 100644 --- a/ecmascript/compiler/aot_file/module_section_des.cpp +++ b/ecmascript/compiler/aot_file/module_section_des.cpp @@ -18,113 +18,6 @@ #include namespace panda::ecmascript { -void ModuleSectionDes::SaveSectionsInfo(std::ofstream &file) -{ - uint32_t secInfoSize = GetSecInfosSize(); - uint32_t secSize = 0; - file.write(reinterpret_cast(&secInfoSize), sizeof(secInfoSize)); - std::multimap SecMap; - for (auto &s : sectionsInfo_) { - uint8_t secName = static_cast(s.first); - uint32_t curSecSize = GetSecSize(s.first); - uint64_t curSecAddr = GetSecAddr(s.first); - secSize += curSecSize; - SecMap.insert(make_pair(GetSecName(s.first), static_cast(curSecSize))); - file.write(reinterpret_cast(&secName), sizeof(secName)); - file.write(reinterpret_cast(&curSecSize), sizeof(curSecSize)); - file.write(reinterpret_cast(curSecAddr), curSecSize); - } - std::shared_ptr ptr = GetArkStackMapSharePtr(); - uint32_t size = GetArkStackMapSize(); - file.write(reinterpret_cast(&size), sizeof(size)); - file.write(reinterpret_cast(ptr.get()), size); - - uint32_t index = GetStartIndex(); - uint32_t cnt = GetFuncCount(); - file.write(reinterpret_cast(&index), sizeof(index)); - file.write(reinterpret_cast(&cnt), sizeof(cnt)); - for (auto [key, val] : SecMap) { - LOG_COMPILER(DEBUG) << key << " size is " << std::fixed << std::setprecision(DECIMAL_LENS) << (val / 1_KB) - << "KB " - << "percentage:" << std::fixed << std::setprecision(PERCENT_LENS) - << (val / secSize * HUNDRED_TIME) << "% "; - } - LOG_COMPILER(DEBUG) << "elf sections size = " << (secSize / 1_KB) << "KB" - << ", ark stack map size = " << (size / 1_KB) << "KB"; -} - -void ModuleSectionDes::LoadStackMapSection(BinaryBufferParser &parser, uintptr_t secBegin, uint32_t &curUnitOffset) -{ - uint32_t size = 0; - parser.ParseBuffer(&size, sizeof(size)); - parser.ParseBuffer(reinterpret_cast(secBegin), size); - SetArkStackMapSize(size); - SetArkStackMapPtr(reinterpret_cast(secBegin)); - curUnitOffset += size; - uint32_t index = 0; - uint32_t cnt = 0; - parser.ParseBuffer(&index, sizeof(index)); - parser.ParseBuffer(&cnt, sizeof(cnt)); - SetStartIndex(index); - SetFuncCount(cnt); -} - -void ModuleSectionDes::LoadSectionsInfo(BinaryBufferParser &parser, uint32_t &curUnitOffset, uint64_t codeAddress) -{ - uint32_t secInfoSize = 0; - parser.ParseBuffer(&secInfoSize, sizeof(secInfoSize)); - auto secBegin = codeAddress + static_cast(curUnitOffset); - for (uint8_t i = 0; i < secInfoSize; i++) { - uint8_t secName = 0; - parser.ParseBuffer(&secName, sizeof(secName)); - auto secEnumName = static_cast(secName); - uint32_t secSize = 0; - parser.ParseBuffer(&secSize, sizeof(secSize)); - SetSecSize(secSize, secEnumName); - parser.ParseBuffer(reinterpret_cast(secBegin), secSize); - curUnitOffset += secSize; - SetSecAddr(secBegin, secEnumName); - secBegin += secSize; - } - LoadStackMapSection(parser, secBegin, curUnitOffset); -} - -void ModuleSectionDes::LoadStackMapSection(std::ifstream &file, uintptr_t secBegin, uint32_t &curUnitOffset) -{ - uint32_t size = 0; - file.read(reinterpret_cast(&size), sizeof(size)); - file.read(reinterpret_cast(secBegin), size); - SetArkStackMapSize(size); - SetArkStackMapPtr(reinterpret_cast(secBegin)); - curUnitOffset += size; - uint32_t index = 0; - uint32_t cnt = 0; - file.read(reinterpret_cast(&index), sizeof(index)); - file.read(reinterpret_cast(&cnt), sizeof(cnt)); - SetStartIndex(index); - SetFuncCount(cnt); -} - -void ModuleSectionDes::LoadSectionsInfo(std::ifstream &file, uint32_t &curUnitOffset, uint64_t codeAddress) -{ - uint32_t secInfoSize = 0; - file.read(reinterpret_cast(&secInfoSize), sizeof(secInfoSize)); - auto secBegin = codeAddress + static_cast(curUnitOffset); - for (uint8_t i = 0; i < secInfoSize; i++) { - uint8_t secName = 0; - file.read(reinterpret_cast(&secName), sizeof(secName)); - auto secEnumName = static_cast(secName); - uint32_t secSize; - file.read(reinterpret_cast(&secSize), sizeof(secSize)); - SetSecSize(secSize, secEnumName); - file.read(reinterpret_cast(secBegin), secSize); - curUnitOffset += secSize; - SetSecAddr(secBegin, secEnumName); - secBegin += secSize; - } - LoadStackMapSection(file, secBegin, curUnitOffset); -} - std::string ModuleSectionDes::GetSecName(const ElfSecName idx) { switch (idx) { @@ -156,6 +49,10 @@ std::string ModuleSectionDes::GetSecName(const ElfSecName idx) return ".ark_stackmaps"; case ElfSecName::ARK_FUNCENTRY: return ".ark_funcentry"; + case ElfSecName::ARK_ASMSTUB: + return ".ark_asmstub"; + case ElfSecName::ARK_MODULEINFO: + return ".ark_moduleinfo"; default: { LOG_ECMA(FATAL) << "this branch is unreachable"; UNREACHABLE(); diff --git a/ecmascript/compiler/aot_file/module_section_des.h b/ecmascript/compiler/aot_file/module_section_des.h index a13c876d8c..40be3eb40a 100644 --- a/ecmascript/compiler/aot_file/module_section_des.h +++ b/ecmascript/compiler/aot_file/module_section_des.h @@ -24,6 +24,13 @@ namespace panda::ecmascript { class ModuleSectionDes { public: + struct ModuleRegionInfo { + uint32_t startIndex {0}; + uint32_t funcCount {0}; + uint32_t rodataSize {0}; + uint32_t textSize {0}; + uint32_t stackMapSize {0}; + }; static std::string GetSecName(ElfSecName idx); void SetArkStackMapPtr(std::shared_ptr ptr) @@ -88,9 +95,15 @@ public: ModuleSectionDes() = default; - void SetSecAddr(uint64_t addr, ElfSecName idx) + void EraseSec(ElfSecName idx) + { + sectionsInfo_.erase(idx); + } + + void SetSecAddrAndSize(ElfSecName idx, uint64_t addr, uint32_t size) { sectionsInfo_[idx].first = addr; + sectionsInfo_[idx].second = size; } uint64_t GetSecAddr(const ElfSecName idx) const @@ -99,16 +112,6 @@ public: return it == sectionsInfo_.end() ? 0 : it->second.first; } - void EraseSec(ElfSecName idx) - { - sectionsInfo_.erase(idx); - } - - void SetSecSize(uint32_t size, ElfSecName idx) - { - sectionsInfo_[idx].second = size; - } - uint32_t GetSecSize(const ElfSecName idx) const { auto it = sectionsInfo_.find(idx); @@ -127,12 +130,6 @@ public: return (pc >= stubStartAddr && pc <= stubEndAddr); } - void SaveSectionsInfo(std::ofstream &file); - void LoadSectionsInfo(BinaryBufferParser &parser, uint32_t &curUnitOffset, uint64_t codeAddress); - void LoadStackMapSection(BinaryBufferParser &parser, uintptr_t secBegin, uint32_t &curUnitOffset); - void LoadSectionsInfo(std::ifstream &file, uint32_t &curUnitOffset, uint64_t codeAddress); - void LoadStackMapSection(std::ifstream &file, uintptr_t secBegin, uint32_t &curUnitOffset); - private: static constexpr int DECIMAL_LENS = 2; static constexpr int HUNDRED_TIME = 100; diff --git a/ecmascript/compiler/aot_file/stub_file_info.cpp b/ecmascript/compiler/aot_file/stub_file_info.cpp index 8044aef7f3..6e0f5d2688 100644 --- a/ecmascript/compiler/aot_file/stub_file_info.cpp +++ b/ecmascript/compiler/aot_file/stub_file_info.cpp @@ -14,6 +14,10 @@ */ #include "ecmascript/compiler/aot_file/stub_file_info.h" +#include "ecmascript/compiler/aot_file/aot_version.h" +#include "ecmascript/compiler/aot_file/elf_builder.h" +#include "ecmascript/compiler/aot_file/elf_reader.h" +#include "ecmascript/compiler/binary_section.h" #include "ecmascript/js_file_path.h" #include "ecmascript/platform/file.h" @@ -21,32 +25,86 @@ extern const uint8_t _binary_stub_an_start[]; extern const uint32_t _binary_stub_an_length; namespace panda::ecmascript { -void StubFileInfo::Save(const std::string &filename) +void StubFileInfo::Save(const std::string &filename, Triple triple) { std::string realPath; if (!RealPath(filename, realPath, false)) { return; } - if (totalCodeSize_ == 0) { - LOG_COMPILER(FATAL) << "error: code size of generated stubs is empty!"; + std::ofstream file(realPath.c_str(), std::ofstream::binary); + ASSERT(GetCodeUnitsNum() == ASMSTUB_MODULE_NUM); + SetStubNum(entries_.size()); + ModuleSectionDes &des = des_[0]; + // add section + uint64_t funcEntryAddr = reinterpret_cast(entries_.data()); + uint32_t funcEntrySize = sizeof(FuncEntryDes) * entryNum_; + des.SetSecAddrAndSize(ElfSecName::ARK_FUNCENTRY, funcEntryAddr, funcEntrySize); + uint64_t asmStubAddr = GetAsmStubAddr(); + uint32_t asmStubSize = GetAsmStubSize(); + des.SetSecAddrAndSize(ElfSecName::ARK_ASMSTUB, asmStubAddr, asmStubSize); + std::vector moduleInfo = {1}; + uint64_t secSizeInfoAddr = reinterpret_cast(moduleInfo.data()); + des.SetSecAddrAndSize(ElfSecName::ARK_MODULEINFO, secSizeInfoAddr, sizeof(uint32_t)); + + ElfBuilder builder(des_, GetDumpSectionNames()); + llvm::ELF::Elf64_Ehdr header; + builder.PackELFHeader(header, base::FileHeader::ToVersionNumber(AOTFileVersion::AN_VERSION), triple); + file.write(reinterpret_cast(&header), sizeof(llvm::ELF::Elf64_Ehdr)); + builder.PackStubELFSections(file); + builder.PackELFSegment(file); + file.close(); +} + +bool StubFileInfo::MmapLoad() +{ + std::string filename = STUB_AN_FILE; + std::string realPath; + if (!RealPath(filename, realPath, false)) { + LOG_COMPILER(ERROR) << "Can not load stub file from path [ " << filename << " ], " + << "please execute ark_stub_compiler with options --stub-file."; + return false; } - std::ofstream file(realPath.c_str(), std::ofstream::binary); - SetStubNum(entries_.size()); - file.write(reinterpret_cast(&entryNum_), sizeof(entryNum_)); - file.write(reinterpret_cast(entries_.data()), sizeof(FuncEntryDes) * entryNum_); - uint32_t moduleNum = GetCodeUnitsNum(); - file.write(reinterpret_cast(&moduleNum), sizeof(moduleNum_)); - file.write(reinterpret_cast(&totalCodeSize_), sizeof(totalCodeSize_)); - uint32_t asmStubSize = GetAsmStubSize(); - file.write(reinterpret_cast(&asmStubSize), sizeof(asmStubSize)); - uint64_t asmStubAddr = GetAsmStubAddr(); - file.write(reinterpret_cast(asmStubAddr), asmStubSize); - for (size_t i = 0; i < moduleNum; i++) { - des_[i].SaveSectionsInfo(file); + fileMapMem_ = FileMap(realPath.c_str(), FILE_RDONLY, PAGE_PROT_READ); + if (fileMapMem_.GetOriginAddr() == nullptr) { + LOG_ECMA(ERROR) << "File mmap failed"; + return false; } - file.close(); + PagePreRead(fileMapMem_.GetOriginAddr(), fileMapMem_.GetSize()); + moduleNum_ = ASMSTUB_MODULE_NUM; + des_.resize(moduleNum_); + + ElfReader reader(fileMapMem_); + std::vector secs = GetDumpSectionNames(); + reader.ParseELFSections(des_, secs); + if (!reader.ParseELFSegment()) { + LOG_ECMA(ERROR) << "modify mmap area permission failed"; + return false; + } + + ModuleSectionDes &des = des_[0]; + uint64_t funcEntryAddr = des.GetSecAddr(ElfSecName::ARK_FUNCENTRY); + uint32_t funcEntrySize = des.GetSecSize(ElfSecName::ARK_FUNCENTRY); + FuncEntryDes *entryDes = reinterpret_cast(funcEntryAddr); + entryNum_ = funcEntrySize / sizeof(FuncEntryDes); + entries_.assign(entryDes, entryDes + entryNum_); + uint64_t asmStubAddr = des.GetSecAddr(ElfSecName::ARK_ASMSTUB); + uint32_t asmStubSize = des.GetSecSize(ElfSecName::ARK_ASMSTUB); + SetAsmStubAddr(asmStubAddr); + SetAsmStubSize(asmStubSize); + + for (auto &entry : entries_) { + if (entry.IsGeneralRTStub()) { + uint64_t begin = GetAsmStubAddr(); + entry.codeAddr_ += begin; + } else { + auto moduleDes = des_[entry.moduleIndex_]; + entry.codeAddr_ += moduleDes.GetSecAddr(ElfSecName::TEXT); + } + } + LOG_COMPILER(INFO) << "loaded stub file successfully"; + return true; } bool StubFileInfo::Load() @@ -57,31 +115,25 @@ bool StubFileInfo::Load() } BinaryBufferParser binBufparser(const_cast(_binary_stub_an_start), _binary_stub_an_length); - binBufparser.ParseBuffer(&entryNum_, sizeof(entryNum_)); - entries_.resize(entryNum_); - binBufparser.ParseBuffer(entries_.data(), sizeof(FuncEntryDes) * entryNum_); - binBufparser.ParseBuffer(&moduleNum_, sizeof(moduleNum_)); + moduleNum_ = ASMSTUB_MODULE_NUM; des_.resize(moduleNum_); - binBufparser.ParseBuffer(&totalCodeSize_, sizeof(totalCodeSize_)); - if (totalCodeSize_ == 0) { - LOG_COMPILER(ERROR) << "error: code in the binary stub is empty!"; - return false; - } + ExecutedMemoryAllocator::AllocateBuf(_binary_stub_an_length, stubsMem_); - ExecutedMemoryAllocator::AllocateBuf(totalCodeSize_, stubsMem_); - uint64_t codeAddress = reinterpret_cast(stubsMem_.addr_); - uint32_t curUnitOffset = 0; - uint32_t asmStubSize = 0; - binBufparser.ParseBuffer(&asmStubSize, sizeof(asmStubSize)); + ElfReader reader(stubsMem_); + std::vector secs = GetDumpSectionNames(); + reader.ParseELFSections(binBufparser, des_, secs); + + ModuleSectionDes &des = des_[0]; + uint64_t funcEntryAddr = des.GetSecAddr(ElfSecName::ARK_FUNCENTRY); + uint32_t funcEntrySize = des.GetSecSize(ElfSecName::ARK_FUNCENTRY); + FuncEntryDes *entryDes = reinterpret_cast(funcEntryAddr); + entryNum_ = funcEntrySize / sizeof(FuncEntryDes); + entries_.assign(entryDes, entryDes + entryNum_); + uint64_t asmStubAddr = des.GetSecAddr(ElfSecName::ARK_ASMSTUB); + uint32_t asmStubSize = des.GetSecSize(ElfSecName::ARK_ASMSTUB); + SetAsmStubAddr(asmStubAddr); SetAsmStubSize(asmStubSize); - binBufparser.ParseBuffer(reinterpret_cast(codeAddress), asmStubSize); - SetAsmStubAddr(codeAddress); - curUnitOffset += asmStubSize; - - for (size_t i = 0; i < moduleNum_; i++) { - des_[i].LoadSectionsInfo(binBufparser, curUnitOffset, codeAddress); - } for (auto &entry : entries_) { if (entry.IsGeneralRTStub()) { @@ -97,6 +149,14 @@ bool StubFileInfo::Load() return true; } +const std::vector &StubFileInfo::GetDumpSectionNames() +{ + static const std::vector secNames = {ElfSecName::TEXT, ElfSecName::STRTAB, + ElfSecName::ARK_STACKMAP, ElfSecName::ARK_FUNCENTRY, + ElfSecName::ARK_ASMSTUB, ElfSecName::ARK_MODULEINFO}; + return secNames; +} + void StubFileInfo::Dump() const { uint64_t asmAddr = GetAsmStubAddr(); diff --git a/ecmascript/compiler/aot_file/stub_file_info.h b/ecmascript/compiler/aot_file/stub_file_info.h index 8ab747ec97..ce69103a1a 100644 --- a/ecmascript/compiler/aot_file/stub_file_info.h +++ b/ecmascript/compiler/aot_file/stub_file_info.h @@ -22,7 +22,7 @@ class PUBLIC_API StubFileInfo : public AOTFileInfo { public: StubFileInfo() = default; ~StubFileInfo() override = default; - void Save(const std::string &filename); + void Save(const std::string &filename, Triple triple); void AddModuleDes(ModuleSectionDes &moduleDes) { @@ -75,7 +75,11 @@ public: void Dump() const DUMP_API_ATTR; private: + static constexpr uint32_t ASMSTUB_MODULE_NUM = 3; + + bool MmapLoad(); bool Load(); + const std::vector &GetDumpSectionNames(); void *asmStubAddr_ {nullptr}; size_t asmStubSize_ {0}; std::vector asmStubTempHolder_ {}; diff --git a/ecmascript/compiler/binary_section.h b/ecmascript/compiler/binary_section.h index e22e2cce12..14efaa0735 100644 --- a/ecmascript/compiler/binary_section.h +++ b/ecmascript/compiler/binary_section.h @@ -30,6 +30,7 @@ enum class ElfSecName : uint8_t { RODATA_CST16, RODATA_CST32, TEXT, + ARK_ASMSTUB, DATA, GOT, RELATEXT, @@ -38,6 +39,7 @@ enum class ElfSecName : uint8_t { LLVM_STACKMAP, ARK_FUNCENTRY, ARK_STACKMAP, + ARK_MODULEINFO, SIZE }; @@ -88,12 +90,16 @@ public: value_ = ElfSecName::STRTAB; } else if (str.compare(".symtab") == 0) { value_ = ElfSecName::SYMTAB; - } else if (str.compare(".llvm_stackmaps") == 0) { + } else if (str.compare(".llvm_stackmaps") == 0) { value_ = ElfSecName::LLVM_STACKMAP; - } else if (str.compare(".ark_stackmaps") == 0) { + } else if (str.compare(".ark_stackmaps") == 0) { value_ = ElfSecName::ARK_STACKMAP; - } else if (str.compare(".ark_funcentry") == 0) { + } else if (str.compare(".ark_funcentry") == 0) { value_ = ElfSecName::ARK_FUNCENTRY; + } else if (str.compare(".ark_asmstub") == 0) { + value_ = ElfSecName::ARK_ASMSTUB; + } else if (str.compare(".ark_moduleinfo") == 0) { + value_ = ElfSecName::ARK_MODULEINFO; } InitShTypeAndFlag(); } @@ -108,11 +114,11 @@ public: case ElfSecName::RODATA_CST16: case ElfSecName::RODATA_CST32: case ElfSecName::TEXT: - case ElfSecName::DATA: - case ElfSecName::SYMTAB: case ElfSecName::STRTAB: case ElfSecName::ARK_FUNCENTRY: - case ElfSecName::ARK_STACKMAP: { + case ElfSecName::ARK_ASMSTUB: + case ElfSecName::ARK_STACKMAP: + case ElfSecName::ARK_MODULEINFO: { saveForAot = true; break; } @@ -123,6 +129,26 @@ public: return saveForAot; } + bool ShouldDumpToStubFile() const + { + bool saveForStub = false; + switch (value_) { + case ElfSecName::TEXT: + case ElfSecName::STRTAB: + case ElfSecName::ARK_FUNCENTRY: + case ElfSecName::ARK_ASMSTUB: + case ElfSecName::ARK_STACKMAP: + case ElfSecName::ARK_MODULEINFO: { + saveForStub = true; + break; + } + default: { + break; + } + } + return saveForStub; + } + ElfSecName Value() const { return value_; @@ -150,6 +176,7 @@ public: {ElfSecName::RODATA_CST16, {llvm::ELF::SHT_PROGBITS, llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_MERGE}}, {ElfSecName::RODATA_CST32, {llvm::ELF::SHT_PROGBITS, llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_MERGE}}, {ElfSecName::TEXT, {llvm::ELF::SHT_PROGBITS, llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_EXECINSTR}}, + {ElfSecName::ARK_ASMSTUB, {llvm::ELF::SHT_PROGBITS, llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_EXECINSTR}}, {ElfSecName::DATA, {llvm::ELF::SHT_PROGBITS, llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_WRITE}}, {ElfSecName::GOT, {llvm::ELF::SHT_PROGBITS, llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_WRITE}}, {ElfSecName::RELATEXT, {llvm::ELF::SHT_RELA, llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_WRITE}}, @@ -158,6 +185,7 @@ public: {ElfSecName::LLVM_STACKMAP, {llvm::ELF::SHT_RELA, llvm::ELF::SHF_ALLOC}}, {ElfSecName::ARK_FUNCENTRY, {llvm::ELF::SHF_WRITE, llvm::ELF::SHF_ALLOC}}, {ElfSecName::ARK_STACKMAP, {llvm::ELF::SHF_WRITE, llvm::ELF::SHF_ALLOC}}, + {ElfSecName::ARK_MODULEINFO, {llvm::ELF::SHF_WRITE, llvm::ELF::SHF_ALLOC}}, }; auto it = nameToTypeAndFlag.find(value_); if (it == nameToTypeAndFlag.end()) { diff --git a/ecmascript/compiler/file_generators.cpp b/ecmascript/compiler/file_generators.cpp index 5a186c395a..7f796145af 100644 --- a/ecmascript/compiler/file_generators.cpp +++ b/ecmascript/compiler/file_generators.cpp @@ -126,8 +126,7 @@ void Module::CollectModuleSectionDes(ModuleSectionDes &moduleDes, bool stub) con if (stub && IsRelaSection(sec)) { moduleDes.EraseSec(sec); } else { // aot need relocated; stub don't need collect relocated section - moduleDes.SetSecAddr(reinterpret_cast(secInfo.first), sec); - moduleDes.SetSecSize(secInfo.second, sec); + moduleDes.SetSecAddrAndSize(sec, reinterpret_cast(secInfo.first), secInfo.second); moduleDes.SetStartIndex(startIndex_); moduleDes.SetFuncCount(funcCount_); } @@ -281,7 +280,7 @@ void StubFileGenerator::SaveStubFile(const std::string &filename) RunLLVMAssembler(); RunAsmAssembler(); CollectCodeInfo(); - stubInfo_.Save(filename); + stubInfo_.Save(filename, cfg_.GetTriple()); } void AOTFileGenerator::SaveAOTFile(const std::string &filename)