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_reader.h"
174514f5e3Sopenharmony_ci
184514f5e3Sopenharmony_cinamespace panda::ecmascript {
194514f5e3Sopenharmony_cibool ElfReader::VerifyELFHeader(uint32_t version, bool strictMatch)
204514f5e3Sopenharmony_ci{
214514f5e3Sopenharmony_ci    llvm::ELF::Elf64_Ehdr header = *(reinterpret_cast<llvm::ELF::Elf64_Ehdr *>(fileMapMem_.GetOriginAddr()));
224514f5e3Sopenharmony_ci    if (header.e_ident[llvm::ELF::EI_MAG0] != llvm::ELF::ElfMagic[llvm::ELF::EI_MAG0]
234514f5e3Sopenharmony_ci        || header.e_ident[llvm::ELF::EI_MAG1] != llvm::ELF::ElfMagic[llvm::ELF::EI_MAG1]
244514f5e3Sopenharmony_ci        || header.e_ident[llvm::ELF::EI_MAG2] != llvm::ELF::ElfMagic[llvm::ELF::EI_MAG2]
254514f5e3Sopenharmony_ci        || header.e_ident[llvm::ELF::EI_MAG3] != llvm::ELF::ElfMagic[llvm::ELF::EI_MAG3]) {
264514f5e3Sopenharmony_ci        LOG_ECMA(ERROR) << "ELF format error, expected magic is " << llvm::ELF::ElfMagic
274514f5e3Sopenharmony_ci                        << ", but got " << header.e_ident[llvm::ELF::EI_MAG0] << header.e_ident[llvm::ELF::EI_MAG1]
284514f5e3Sopenharmony_ci                        << header.e_ident[llvm::ELF::EI_MAG2] << header.e_ident[llvm::ELF::EI_MAG3];
294514f5e3Sopenharmony_ci        return false;
304514f5e3Sopenharmony_ci    }
314514f5e3Sopenharmony_ci    if (!base::FileHeaderBase::VerifyVersion("Elf", header.e_version, version, strictMatch)) {
324514f5e3Sopenharmony_ci        return false;
334514f5e3Sopenharmony_ci    }
344514f5e3Sopenharmony_ci    if (ElfChecker(fileMapMem_).CheckValidElf() == false) {
354514f5e3Sopenharmony_ci        LOG_ECMA(ERROR) << "ELF file content is not valid";
364514f5e3Sopenharmony_ci        return false;
374514f5e3Sopenharmony_ci    }
384514f5e3Sopenharmony_ci    return true;
394514f5e3Sopenharmony_ci}
404514f5e3Sopenharmony_ci
414514f5e3Sopenharmony_ciModuleSectionDes::ModuleRegionInfo *ElfReader::GetCurModuleInfo(uint32_t i, llvm::ELF::Elf64_Off offset)
424514f5e3Sopenharmony_ci{
434514f5e3Sopenharmony_ci    uint64_t codeAddress = reinterpret_cast<uint64_t>(fileMapMem_.GetOriginAddr());
444514f5e3Sopenharmony_ci    uint64_t info = codeAddress + offset + i * sizeof(ModuleSectionDes::ModuleRegionInfo);
454514f5e3Sopenharmony_ci    return reinterpret_cast<ModuleSectionDes::ModuleRegionInfo *>(info);
464514f5e3Sopenharmony_ci}
474514f5e3Sopenharmony_ci
484514f5e3Sopenharmony_civoid ElfReader::ParseELFSections(ModuleSectionDes &des, std::vector<ElfSecName> &secs)
494514f5e3Sopenharmony_ci{
504514f5e3Sopenharmony_ci    llvm::ELF::Elf64_Ehdr *ehdr = reinterpret_cast<llvm::ELF::Elf64_Ehdr *>(fileMapMem_.GetOriginAddr());
514514f5e3Sopenharmony_ci    char *addr = reinterpret_cast<char *>(ehdr);
524514f5e3Sopenharmony_ci    llvm::ELF::Elf64_Shdr *shdr = reinterpret_cast<llvm::ELF::Elf64_Shdr *>(addr + ehdr->e_shoff);
534514f5e3Sopenharmony_ci    ASSERT(ehdr->e_shstrndx != static_cast<llvm::ELF::Elf64_Half>(-1));
544514f5e3Sopenharmony_ci    llvm::ELF::Elf64_Shdr strdr = shdr[ehdr->e_shstrndx];
554514f5e3Sopenharmony_ci    for (size_t j = 0; j < secs.size(); ++j) {
564514f5e3Sopenharmony_ci        int secId = -1;
574514f5e3Sopenharmony_ci        ElfSecName sec = secs[j];
584514f5e3Sopenharmony_ci        std::string sectionName = ModuleSectionDes::GetSecName(sec);
594514f5e3Sopenharmony_ci        for (size_t i = 0; i < ehdr->e_shnum; ++i) {
604514f5e3Sopenharmony_ci            llvm::ELF::Elf64_Word shName = shdr[i].sh_name;
614514f5e3Sopenharmony_ci            char *curShName = reinterpret_cast<char *>(addr) + shName + strdr.sh_offset;
624514f5e3Sopenharmony_ci            if (sectionName.compare(curShName) == 0) {
634514f5e3Sopenharmony_ci                secId = static_cast<int>(i);
644514f5e3Sopenharmony_ci                break;
654514f5e3Sopenharmony_ci            }
664514f5e3Sopenharmony_ci        }
674514f5e3Sopenharmony_ci        if (secId == -1) {
684514f5e3Sopenharmony_ci            LOG_COMPILER(DEBUG) << "sectionName: " << sectionName << " not found in strtab";
694514f5e3Sopenharmony_ci            continue;
704514f5e3Sopenharmony_ci        }
714514f5e3Sopenharmony_ci        ASSERT(secId > 0 && secId < ehdr->e_shnum);
724514f5e3Sopenharmony_ci        llvm::ELF::Elf64_Shdr secShdr = shdr[secId];
734514f5e3Sopenharmony_ci        uintptr_t secAddr = reinterpret_cast<uintptr_t>(addr + secShdr.sh_offset);
744514f5e3Sopenharmony_ci        uint32_t secSize = secShdr.sh_size;
754514f5e3Sopenharmony_ci        if (sec == ElfSecName::ARK_FUNCENTRY) {
764514f5e3Sopenharmony_ci            ASSERT((secSize > 0) && (secSize % sizeof(AOTFileInfo::FuncEntryDes) == 0));
774514f5e3Sopenharmony_ci        }
784514f5e3Sopenharmony_ci        if (sec == ElfSecName::ARK_STACKMAP) {
794514f5e3Sopenharmony_ci            des.SetArkStackMapPtr(reinterpret_cast<uint8_t *>(secAddr));
804514f5e3Sopenharmony_ci            des.SetArkStackMapSize(secSize);
814514f5e3Sopenharmony_ci        } else {
824514f5e3Sopenharmony_ci            des.SetSecAddrAndSize(sec, secAddr, secSize);
834514f5e3Sopenharmony_ci        }
844514f5e3Sopenharmony_ci    }
854514f5e3Sopenharmony_ci}
864514f5e3Sopenharmony_ci
874514f5e3Sopenharmony_civoid ElfReader::ParseELFSections(std::vector<ModuleSectionDes> &des, std::vector<ElfSecName> &secs)
884514f5e3Sopenharmony_ci{
894514f5e3Sopenharmony_ci    llvm::ELF::Elf64_Ehdr *ehdr = reinterpret_cast<llvm::ELF::Elf64_Ehdr *>(fileMapMem_.GetOriginAddr());
904514f5e3Sopenharmony_ci    char *addr = reinterpret_cast<char *>(ehdr);
914514f5e3Sopenharmony_ci    llvm::ELF::Elf64_Shdr *shdrs = reinterpret_cast<llvm::ELF::Elf64_Shdr *>(addr + ehdr->e_shoff);
924514f5e3Sopenharmony_ci    ASSERT(ehdr->e_shstrndx != static_cast<llvm::ELF::Elf64_Half>(-1));
934514f5e3Sopenharmony_ci    llvm::ELF::Elf64_Shdr strdr = shdrs[ehdr->e_shstrndx];
944514f5e3Sopenharmony_ci    ASSERT(ehdr->e_flags != static_cast<llvm::ELF::Elf64_Word>(-1));
954514f5e3Sopenharmony_ci    llvm::ELF::Elf64_Shdr moduledr = shdrs[ehdr->e_flags];
964514f5e3Sopenharmony_ci    size_t moduleInfoSize = moduledr.sh_size;
974514f5e3Sopenharmony_ci    uint32_t moduleNum = GetModuleNum(moduleInfoSize);
984514f5e3Sopenharmony_ci    des.resize(moduleNum);
994514f5e3Sopenharmony_ci    std::set<ElfSecName> secSet(secs.begin(), secs.end());
1004514f5e3Sopenharmony_ci    for (ElfSecName sec : secSet) {
1014514f5e3Sopenharmony_ci        int secId = -1;
1024514f5e3Sopenharmony_ci        std::string sectionName = ModuleSectionDes::GetSecName(sec);
1034514f5e3Sopenharmony_ci        for (size_t i = 0; i < ehdr->e_shnum; ++i) {
1044514f5e3Sopenharmony_ci            llvm::ELF::Elf64_Word shName = shdrs[i].sh_name;
1054514f5e3Sopenharmony_ci            char *curShName = reinterpret_cast<char *>(addr) + shName + strdr.sh_offset;
1064514f5e3Sopenharmony_ci            if (sectionName.compare(curShName) == 0) {
1074514f5e3Sopenharmony_ci                secId = static_cast<int>(i);
1084514f5e3Sopenharmony_ci                break;
1094514f5e3Sopenharmony_ci            }
1104514f5e3Sopenharmony_ci        }
1114514f5e3Sopenharmony_ci        if (secId == -1) {
1124514f5e3Sopenharmony_ci            LOG_COMPILER(DEBUG) << "sectionName: " << sectionName << " not found in strtab";
1134514f5e3Sopenharmony_ci            continue;
1144514f5e3Sopenharmony_ci        }
1154514f5e3Sopenharmony_ci        ASSERT(secId > 0 && secId < ehdr->e_shnum);
1164514f5e3Sopenharmony_ci        llvm::ELF::Elf64_Shdr secShdr = shdrs[secId];
1174514f5e3Sopenharmony_ci        uintptr_t secAddr = reinterpret_cast<uintptr_t>(addr + secShdr.sh_offset);
1184514f5e3Sopenharmony_ci        uint32_t secSize = secShdr.sh_size;
1194514f5e3Sopenharmony_ci        switch (sec) {
1204514f5e3Sopenharmony_ci            case ElfSecName::TEXT: {
1214514f5e3Sopenharmony_ci                llvm::ELF::Elf64_Off secOffset = 0;
1224514f5e3Sopenharmony_ci                SeparateTextSections(des, secAddr, secOffset, moduledr.sh_offset);
1234514f5e3Sopenharmony_ci                ASSERT(static_cast<uint32_t>(secOffset) == secSize);
1244514f5e3Sopenharmony_ci                break;
1254514f5e3Sopenharmony_ci            }
1264514f5e3Sopenharmony_ci            case ElfSecName::ARK_STACKMAP: {
1274514f5e3Sopenharmony_ci                llvm::ELF::Elf64_Off secOffset = 0;
1284514f5e3Sopenharmony_ci                SeparateArkStackMapSections(des, secAddr, secOffset, moduledr.sh_offset);
1294514f5e3Sopenharmony_ci                ASSERT(static_cast<uint32_t>(secOffset) == secSize);
1304514f5e3Sopenharmony_ci                break;
1314514f5e3Sopenharmony_ci            }
1324514f5e3Sopenharmony_ci            case ElfSecName::STRTAB: {
1334514f5e3Sopenharmony_ci                llvm::ELF::Elf64_Off secOffset = 0;
1344514f5e3Sopenharmony_ci                SeparateStrtabSections(des, secAddr, secOffset, moduledr.sh_offset);
1354514f5e3Sopenharmony_ci                ASSERT(static_cast<uint32_t>(secOffset) == secSize);
1364514f5e3Sopenharmony_ci                break;
1374514f5e3Sopenharmony_ci            }
1384514f5e3Sopenharmony_ci            case ElfSecName::SYMTAB: {
1394514f5e3Sopenharmony_ci                llvm::ELF::Elf64_Off secOffset = 0;
1404514f5e3Sopenharmony_ci                SeparateSymtabSections(des, secAddr, secOffset, moduledr.sh_offset);
1414514f5e3Sopenharmony_ci                ASSERT(static_cast<uint32_t>(secOffset) == secSize);
1424514f5e3Sopenharmony_ci                break;
1434514f5e3Sopenharmony_ci            }
1444514f5e3Sopenharmony_ci            case ElfSecName::SHSTRTAB:
1454514f5e3Sopenharmony_ci            case ElfSecName::ARK_FUNCENTRY:
1464514f5e3Sopenharmony_ci            case ElfSecName::ARK_ASMSTUB:
1474514f5e3Sopenharmony_ci            case ElfSecName::ARK_MODULEINFO: {
1484514f5e3Sopenharmony_ci                if (sec == ElfSecName::ARK_FUNCENTRY) {
1494514f5e3Sopenharmony_ci                    ASSERT((secSize > 0) && (secSize % sizeof(AOTFileInfo::FuncEntryDes) == 0));
1504514f5e3Sopenharmony_ci                }
1514514f5e3Sopenharmony_ci                des[0].SetSecAddrAndSize(sec, secAddr, secSize);
1524514f5e3Sopenharmony_ci                break;
1534514f5e3Sopenharmony_ci            }
1544514f5e3Sopenharmony_ci            default: {
1554514f5e3Sopenharmony_ci                LOG_ECMA(FATAL) << "this section should not dump to stub file";
1564514f5e3Sopenharmony_ci                break;
1574514f5e3Sopenharmony_ci            }
1584514f5e3Sopenharmony_ci        }
1594514f5e3Sopenharmony_ci    }
1604514f5e3Sopenharmony_ci}
1614514f5e3Sopenharmony_ci
1624514f5e3Sopenharmony_civoid ElfReader::ParseELFSections(BinaryBufferParser &parser,
1634514f5e3Sopenharmony_ci                                 std::vector<ModuleSectionDes> &des,
1644514f5e3Sopenharmony_ci                                 std::vector<ElfSecName> &secs)
1654514f5e3Sopenharmony_ci{
1664514f5e3Sopenharmony_ci    ASSERT(des.size() == ASMSTUB_MODULE_NUM);
1674514f5e3Sopenharmony_ci    uint64_t codeAddress = reinterpret_cast<uint64_t>(stubsMem_.addr_);
1684514f5e3Sopenharmony_ci    llvm::ELF::Elf64_Ehdr ehdr;
1694514f5e3Sopenharmony_ci    parser.ParseBuffer(&ehdr, sizeof(ehdr), 0);
1704514f5e3Sopenharmony_ci    std::vector<llvm::ELF::Elf64_Shdr> shdrs(ehdr.e_shnum);
1714514f5e3Sopenharmony_ci    parser.ParseBuffer(shdrs.data(), sizeof(llvm::ELF::Elf64_Shdr) * ehdr.e_shnum, ehdr.e_shoff);
1724514f5e3Sopenharmony_ci
1734514f5e3Sopenharmony_ci    ASSERT(ehdr.e_shstrndx != static_cast<llvm::ELF::Elf64_Half>(-1));
1744514f5e3Sopenharmony_ci    llvm::ELF::Elf64_Shdr strdr = shdrs[ehdr.e_shstrndx];
1754514f5e3Sopenharmony_ci    ASSERT(ehdr.e_flags != static_cast<llvm::ELF::Elf64_Word>(-1));
1764514f5e3Sopenharmony_ci    llvm::ELF::Elf64_Shdr moduledr = shdrs[ehdr.e_flags];
1774514f5e3Sopenharmony_ci    [[maybe_unused]] size_t moduleInfoSize = moduledr.sh_size;
1784514f5e3Sopenharmony_ci    uint32_t moduleNum = GetModuleNum(moduleInfoSize);
1794514f5e3Sopenharmony_ci    ASSERT(moduleNum == ASMSTUB_MODULE_NUM);
1804514f5e3Sopenharmony_ci    moduleInfo_.resize(moduleNum);
1814514f5e3Sopenharmony_ci    parser.ParseBuffer(moduleInfo_.data(), moduleInfoSize, moduledr.sh_offset);
1824514f5e3Sopenharmony_ci    std::set<ElfSecName> secSet(secs.begin(), secs.end());
1834514f5e3Sopenharmony_ci    for (ElfSecName sec : secSet) {
1844514f5e3Sopenharmony_ci        int secId = -1;
1854514f5e3Sopenharmony_ci        std::string sectionName = ModuleSectionDes::GetSecName(sec);
1864514f5e3Sopenharmony_ci        for (size_t i = 0; i < ehdr.e_shnum; ++i) {
1874514f5e3Sopenharmony_ci            llvm::ELF::Elf64_Word shName = shdrs[i].sh_name;
1884514f5e3Sopenharmony_ci            char *curShName = reinterpret_cast<char *>(parser.GetAddr()) + shName + strdr.sh_offset;
1894514f5e3Sopenharmony_ci            if (sectionName.compare(curShName) == 0) {
1904514f5e3Sopenharmony_ci                secId = static_cast<int>(i);
1914514f5e3Sopenharmony_ci                break;
1924514f5e3Sopenharmony_ci            }
1934514f5e3Sopenharmony_ci        }
1944514f5e3Sopenharmony_ci        if (secId == -1) {
1954514f5e3Sopenharmony_ci            LOG_COMPILER(DEBUG) << "sectionName: " << sectionName << " not found in strtab";
1964514f5e3Sopenharmony_ci            continue;
1974514f5e3Sopenharmony_ci        }
1984514f5e3Sopenharmony_ci        ASSERT(secId > 0 && secId < ehdr.e_shnum);
1994514f5e3Sopenharmony_ci        llvm::ELF::Elf64_Shdr secShdr = shdrs[secId];
2004514f5e3Sopenharmony_ci        uint64_t secAddr = static_cast<uint64_t>(codeAddress + secShdr.sh_offset);
2014514f5e3Sopenharmony_ci        uint32_t secSize = secShdr.sh_size;
2024514f5e3Sopenharmony_ci        switch (sec) {
2034514f5e3Sopenharmony_ci            case ElfSecName::TEXT: {
2044514f5e3Sopenharmony_ci                llvm::ELF::Elf64_Off secOffset = 0;
2054514f5e3Sopenharmony_ci                SeparateTextSections(parser, des, secAddr, secOffset, secShdr.sh_offset);
2064514f5e3Sopenharmony_ci                ASSERT(static_cast<uint32_t>(secOffset) == secSize);
2074514f5e3Sopenharmony_ci                break;
2084514f5e3Sopenharmony_ci            }
2094514f5e3Sopenharmony_ci            case ElfSecName::ARK_STACKMAP: {
2104514f5e3Sopenharmony_ci                llvm::ELF::Elf64_Off secOffset = 0;
2114514f5e3Sopenharmony_ci                SeparateArkStackMapSections(parser, des, secAddr, secOffset, secShdr.sh_offset);
2124514f5e3Sopenharmony_ci                ASSERT(static_cast<uint32_t>(secOffset) == secSize);
2134514f5e3Sopenharmony_ci                break;
2144514f5e3Sopenharmony_ci            }
2154514f5e3Sopenharmony_ci            case ElfSecName::STRTAB: {
2164514f5e3Sopenharmony_ci                llvm::ELF::Elf64_Off secOffset = 0;
2174514f5e3Sopenharmony_ci                SeparateStrtabSections(parser, des, secAddr, secOffset, secShdr.sh_offset);
2184514f5e3Sopenharmony_ci                ASSERT(static_cast<uint32_t>(secOffset) == secSize);
2194514f5e3Sopenharmony_ci                break;
2204514f5e3Sopenharmony_ci            }
2214514f5e3Sopenharmony_ci            case ElfSecName::SYMTAB: {
2224514f5e3Sopenharmony_ci                llvm::ELF::Elf64_Off secOffset = 0;
2234514f5e3Sopenharmony_ci                SeparateSymtabSections(parser, des, secAddr, secOffset, secShdr.sh_offset);
2244514f5e3Sopenharmony_ci                ASSERT(static_cast<uint32_t>(secOffset) == secSize);
2254514f5e3Sopenharmony_ci                break;
2264514f5e3Sopenharmony_ci            }
2274514f5e3Sopenharmony_ci            case ElfSecName::SHSTRTAB:
2284514f5e3Sopenharmony_ci            case ElfSecName::ARK_FUNCENTRY:
2294514f5e3Sopenharmony_ci            case ElfSecName::ARK_ASMSTUB:
2304514f5e3Sopenharmony_ci            case ElfSecName::ARK_MODULEINFO: {
2314514f5e3Sopenharmony_ci                if (sec == ElfSecName::ARK_FUNCENTRY) {
2324514f5e3Sopenharmony_ci                    ASSERT((secSize > 0) && (secSize % sizeof(AOTFileInfo::FuncEntryDes) == 0));
2334514f5e3Sopenharmony_ci                }
2344514f5e3Sopenharmony_ci                parser.ParseBuffer(reinterpret_cast<void *>(secAddr), secSize, secShdr.sh_offset);
2354514f5e3Sopenharmony_ci                des[0].SetSecAddrAndSize(sec, secAddr, secSize);
2364514f5e3Sopenharmony_ci                break;
2374514f5e3Sopenharmony_ci            }
2384514f5e3Sopenharmony_ci            default: {
2394514f5e3Sopenharmony_ci                LOG_ECMA(FATAL) << "this section should not dump to stub file";
2404514f5e3Sopenharmony_ci                break;
2414514f5e3Sopenharmony_ci            }
2424514f5e3Sopenharmony_ci        }
2434514f5e3Sopenharmony_ci    }
2444514f5e3Sopenharmony_ci}
2454514f5e3Sopenharmony_ci
2464514f5e3Sopenharmony_cibool ElfReader::ParseELFSegment()
2474514f5e3Sopenharmony_ci{
2484514f5e3Sopenharmony_ci    if (fileMapMem_.GetOriginAddr() == nullptr) {
2494514f5e3Sopenharmony_ci        return false;
2504514f5e3Sopenharmony_ci    }
2514514f5e3Sopenharmony_ci    char *addr = reinterpret_cast<char *>(fileMapMem_.GetOriginAddr());
2524514f5e3Sopenharmony_ci    llvm::ELF::Elf64_Ehdr *ehdr = reinterpret_cast<llvm::ELF::Elf64_Ehdr *>(fileMapMem_.GetOriginAddr());
2534514f5e3Sopenharmony_ci    llvm::ELF::Elf64_Phdr *phdr = reinterpret_cast<llvm::ELF::Elf64_Phdr *>(addr + ehdr->e_phoff);
2544514f5e3Sopenharmony_ci    for (int i = 0; i < ehdr->e_phnum; ++i) {
2554514f5e3Sopenharmony_ci        if (phdr[i].p_type != llvm::ELF::PT_LOAD) {
2564514f5e3Sopenharmony_ci            continue;
2574514f5e3Sopenharmony_ci        }
2584514f5e3Sopenharmony_ci        if (phdr[i].p_filesz > phdr[i].p_memsz) {
2594514f5e3Sopenharmony_ci            LOG_COMPILER(ERROR) << " p_filesz:0x" << std::hex << phdr[i].p_filesz << " > p_memsz:0x"
2604514f5e3Sopenharmony_ci                << phdr[i].p_memsz;
2614514f5e3Sopenharmony_ci            return false;
2624514f5e3Sopenharmony_ci        }
2634514f5e3Sopenharmony_ci        if (!phdr[i].p_filesz) {
2644514f5e3Sopenharmony_ci            continue;
2654514f5e3Sopenharmony_ci        }
2664514f5e3Sopenharmony_ci        unsigned char *virtualAddr = reinterpret_cast<unsigned char *>(addr + phdr[i].p_vaddr);
2674514f5e3Sopenharmony_ci        ASSERT(phdr[i].p_offset % PageSize() == 0);
2684514f5e3Sopenharmony_ci        if ((phdr[i].p_flags & llvm::ELF::PF_X) != 0) {
2694514f5e3Sopenharmony_ci            ASSERT(reinterpret_cast<uintptr_t>(virtualAddr) % PageSize() == 0);
2704514f5e3Sopenharmony_ci            if (!PageProtect(virtualAddr, phdr[i].p_memsz, PAGE_PROT_EXEC_READ)) {
2714514f5e3Sopenharmony_ci                return false;
2724514f5e3Sopenharmony_ci            }
2734514f5e3Sopenharmony_ci        }
2744514f5e3Sopenharmony_ci    }
2754514f5e3Sopenharmony_ci    return true;
2764514f5e3Sopenharmony_ci}
2774514f5e3Sopenharmony_ci
2784514f5e3Sopenharmony_civoid ElfReader::SeparateTextSections(std::vector<ModuleSectionDes> &des,
2794514f5e3Sopenharmony_ci                                     const uintptr_t &secAddr,
2804514f5e3Sopenharmony_ci                                     llvm::ELF::Elf64_Off &secOffset,
2814514f5e3Sopenharmony_ci                                     const llvm::ELF::Elf64_Off &moduleInfoOffset)
2824514f5e3Sopenharmony_ci{
2834514f5e3Sopenharmony_ci    for (size_t i = 0; i < des.size(); ++i) {
2844514f5e3Sopenharmony_ci        auto moduleInfo = GetCurModuleInfo(i, moduleInfoOffset);
2854514f5e3Sopenharmony_ci        secOffset = AlignUp(secOffset, AOTFileInfo::PAGE_ALIGN);
2864514f5e3Sopenharmony_ci        uint32_t rodataSizeBeforeText = moduleInfo->rodataSizeBeforeText;
2874514f5e3Sopenharmony_ci        uint32_t rodataSizeAfterText = moduleInfo->rodataSizeAfterText;
2884514f5e3Sopenharmony_ci        if (rodataSizeBeforeText != 0) {
2894514f5e3Sopenharmony_ci            secOffset += rodataSizeBeforeText;
2904514f5e3Sopenharmony_ci            secOffset = AlignUp(secOffset, AOTFileInfo::TEXT_SEC_ALIGN);
2914514f5e3Sopenharmony_ci        }
2924514f5e3Sopenharmony_ci        uint32_t textSize = moduleInfo->textSize;
2934514f5e3Sopenharmony_ci        des[i].SetSecAddrAndSize(ElfSecName::TEXT, secAddr + secOffset, textSize);
2944514f5e3Sopenharmony_ci        secOffset += textSize;
2954514f5e3Sopenharmony_ci        if (rodataSizeAfterText != 0) {
2964514f5e3Sopenharmony_ci            secOffset = AlignUp(secOffset, AOTFileInfo::DATA_SEC_ALIGN);
2974514f5e3Sopenharmony_ci            secOffset += rodataSizeAfterText;
2984514f5e3Sopenharmony_ci        }
2994514f5e3Sopenharmony_ci    }
3004514f5e3Sopenharmony_ci}
3014514f5e3Sopenharmony_ci
3024514f5e3Sopenharmony_civoid ElfReader::SeparateArkStackMapSections(std::vector<ModuleSectionDes> &des,
3034514f5e3Sopenharmony_ci                                            const uintptr_t &secAddr,
3044514f5e3Sopenharmony_ci                                            llvm::ELF::Elf64_Off &secOffset,
3054514f5e3Sopenharmony_ci                                            const llvm::ELF::Elf64_Off &moduleInfoOffset)
3064514f5e3Sopenharmony_ci{
3074514f5e3Sopenharmony_ci    for (size_t i = 0; i < des.size(); ++i) {
3084514f5e3Sopenharmony_ci        auto moduleInfo = GetCurModuleInfo(i, moduleInfoOffset);
3094514f5e3Sopenharmony_ci        uint32_t stackMapSize = moduleInfo->stackMapSize;
3104514f5e3Sopenharmony_ci        des[i].SetArkStackMapPtr(reinterpret_cast<uint8_t *>(secAddr + secOffset));
3114514f5e3Sopenharmony_ci        des[i].SetArkStackMapSize(stackMapSize);
3124514f5e3Sopenharmony_ci        uint32_t index = moduleInfo->startIndex;
3134514f5e3Sopenharmony_ci        uint32_t cnt = moduleInfo->funcCount;
3144514f5e3Sopenharmony_ci        des[i].SetStartIndex(index);
3154514f5e3Sopenharmony_ci        des[i].SetFuncCount(cnt);
3164514f5e3Sopenharmony_ci        secOffset += stackMapSize;
3174514f5e3Sopenharmony_ci    }
3184514f5e3Sopenharmony_ci}
3194514f5e3Sopenharmony_ci
3204514f5e3Sopenharmony_civoid ElfReader::SeparateStrtabSections(std::vector<ModuleSectionDes> &des,
3214514f5e3Sopenharmony_ci                                       const uintptr_t &secAddr,
3224514f5e3Sopenharmony_ci                                       llvm::ELF::Elf64_Off &secOffset,
3234514f5e3Sopenharmony_ci                                       const llvm::ELF::Elf64_Off &moduleInfoOffset)
3244514f5e3Sopenharmony_ci{
3254514f5e3Sopenharmony_ci    for (size_t i = 0; i < des.size(); ++i) {
3264514f5e3Sopenharmony_ci        auto moduleInfo = GetCurModuleInfo(i, moduleInfoOffset);
3274514f5e3Sopenharmony_ci        uint32_t strtabSize = moduleInfo->strtabSize;
3284514f5e3Sopenharmony_ci        des[i].SetSecAddrAndSize(ElfSecName::STRTAB, secAddr + secOffset, strtabSize);
3294514f5e3Sopenharmony_ci        secOffset += strtabSize;
3304514f5e3Sopenharmony_ci    }
3314514f5e3Sopenharmony_ci}
3324514f5e3Sopenharmony_ci
3334514f5e3Sopenharmony_civoid ElfReader::SeparateSymtabSections(std::vector<ModuleSectionDes> &des,
3344514f5e3Sopenharmony_ci                                       const uintptr_t &secAddr,
3354514f5e3Sopenharmony_ci                                       llvm::ELF::Elf64_Off &secOffset,
3364514f5e3Sopenharmony_ci                                       const llvm::ELF::Elf64_Off &moduleInfoOffset)
3374514f5e3Sopenharmony_ci{
3384514f5e3Sopenharmony_ci    for (size_t i = 0; i < des.size(); ++i) {
3394514f5e3Sopenharmony_ci        auto moduleInfo = GetCurModuleInfo(i, moduleInfoOffset);
3404514f5e3Sopenharmony_ci        uint32_t symtabSize = moduleInfo->symtabSize;
3414514f5e3Sopenharmony_ci        des[i].SetSecAddrAndSize(ElfSecName::SYMTAB, secAddr + secOffset, symtabSize);
3424514f5e3Sopenharmony_ci        secOffset += symtabSize;
3434514f5e3Sopenharmony_ci    }
3444514f5e3Sopenharmony_ci}
3454514f5e3Sopenharmony_ci
3464514f5e3Sopenharmony_civoid ElfReader::SeparateTextSections(BinaryBufferParser &parser,
3474514f5e3Sopenharmony_ci                                     std::vector<ModuleSectionDes> &des,
3484514f5e3Sopenharmony_ci                                     const uint64_t &secAddr,
3494514f5e3Sopenharmony_ci                                     llvm::ELF::Elf64_Off &secOffset,
3504514f5e3Sopenharmony_ci                                     const llvm::ELF::Elf64_Off &curShOffset)
3514514f5e3Sopenharmony_ci{
3524514f5e3Sopenharmony_ci    for (size_t i = 0; i < des.size(); ++i) {
3534514f5e3Sopenharmony_ci        auto moduleInfo = moduleInfo_[i];
3544514f5e3Sopenharmony_ci        secOffset = AlignUp(secOffset, AOTFileInfo::PAGE_ALIGN);
3554514f5e3Sopenharmony_ci        uint32_t rodataSizeBeforeText = moduleInfo.rodataSizeBeforeText;
3564514f5e3Sopenharmony_ci        uint32_t rodataSizeAfterText = moduleInfo.rodataSizeAfterText;
3574514f5e3Sopenharmony_ci        if (rodataSizeBeforeText != 0) {
3584514f5e3Sopenharmony_ci            parser.ParseBuffer(reinterpret_cast<void *>(secAddr + secOffset), rodataSizeBeforeText,
3594514f5e3Sopenharmony_ci                               curShOffset + secOffset);
3604514f5e3Sopenharmony_ci            secOffset += rodataSizeBeforeText;
3614514f5e3Sopenharmony_ci            secOffset = AlignUp(secOffset, AOTFileInfo::TEXT_SEC_ALIGN);
3624514f5e3Sopenharmony_ci        }
3634514f5e3Sopenharmony_ci        uint32_t textSize = moduleInfo.textSize;
3644514f5e3Sopenharmony_ci        parser.ParseBuffer(reinterpret_cast<void *>(secAddr + secOffset), textSize, curShOffset + secOffset);
3654514f5e3Sopenharmony_ci        des[i].SetSecAddrAndSize(ElfSecName::TEXT, secAddr + secOffset, textSize);
3664514f5e3Sopenharmony_ci        secOffset += textSize;
3674514f5e3Sopenharmony_ci        if (rodataSizeAfterText != 0) {
3684514f5e3Sopenharmony_ci            secOffset = AlignUp(secOffset, AOTFileInfo::DATA_SEC_ALIGN);
3694514f5e3Sopenharmony_ci            parser.ParseBuffer(reinterpret_cast<void *>(secAddr + secOffset), rodataSizeAfterText,
3704514f5e3Sopenharmony_ci                               curShOffset + secOffset);
3714514f5e3Sopenharmony_ci            secOffset += rodataSizeAfterText;
3724514f5e3Sopenharmony_ci        }
3734514f5e3Sopenharmony_ci    }
3744514f5e3Sopenharmony_ci}
3754514f5e3Sopenharmony_ci
3764514f5e3Sopenharmony_civoid ElfReader::SeparateArkStackMapSections(BinaryBufferParser &parser,
3774514f5e3Sopenharmony_ci                                            std::vector<ModuleSectionDes> &des,
3784514f5e3Sopenharmony_ci                                            const uint64_t &secAddr,
3794514f5e3Sopenharmony_ci                                            llvm::ELF::Elf64_Off &secOffset,
3804514f5e3Sopenharmony_ci                                            const llvm::ELF::Elf64_Off &curShOffset)
3814514f5e3Sopenharmony_ci{
3824514f5e3Sopenharmony_ci    for (size_t i = 0; i < des.size(); ++i) {
3834514f5e3Sopenharmony_ci        auto moduleInfo = moduleInfo_[i];
3844514f5e3Sopenharmony_ci        uint32_t stackMapSize = moduleInfo.stackMapSize;
3854514f5e3Sopenharmony_ci        parser.ParseBuffer(reinterpret_cast<void *>(secAddr + secOffset), stackMapSize, curShOffset + secOffset);
3864514f5e3Sopenharmony_ci        des[i].SetArkStackMapPtr(reinterpret_cast<uint8_t *>(secAddr + secOffset));
3874514f5e3Sopenharmony_ci        des[i].SetArkStackMapSize(stackMapSize);
3884514f5e3Sopenharmony_ci        uint32_t index = moduleInfo.startIndex;
3894514f5e3Sopenharmony_ci        uint32_t cnt = moduleInfo.funcCount;
3904514f5e3Sopenharmony_ci        des[i].SetStartIndex(index);
3914514f5e3Sopenharmony_ci        des[i].SetFuncCount(cnt);
3924514f5e3Sopenharmony_ci        secOffset += stackMapSize;
3934514f5e3Sopenharmony_ci    }
3944514f5e3Sopenharmony_ci}
3954514f5e3Sopenharmony_ci
3964514f5e3Sopenharmony_civoid ElfReader::SeparateStrtabSections(BinaryBufferParser &parser,
3974514f5e3Sopenharmony_ci                                       std::vector<ModuleSectionDes> &des,
3984514f5e3Sopenharmony_ci                                       const uintptr_t &secAddr,
3994514f5e3Sopenharmony_ci                                       llvm::ELF::Elf64_Off &secOffset,
4004514f5e3Sopenharmony_ci                                       const llvm::ELF::Elf64_Off &curShOffset)
4014514f5e3Sopenharmony_ci{
4024514f5e3Sopenharmony_ci    for (size_t i = 0; i < des.size(); ++i) {
4034514f5e3Sopenharmony_ci        auto moduleInfo = moduleInfo_[i];
4044514f5e3Sopenharmony_ci        uint32_t strtabSize = moduleInfo.strtabSize;
4054514f5e3Sopenharmony_ci        parser.ParseBuffer(reinterpret_cast<void *>(secAddr + secOffset), strtabSize, curShOffset + secOffset);
4064514f5e3Sopenharmony_ci        des[i].SetSecAddrAndSize(ElfSecName::STRTAB, secAddr + secOffset, strtabSize);
4074514f5e3Sopenharmony_ci        secOffset += strtabSize;
4084514f5e3Sopenharmony_ci    }
4094514f5e3Sopenharmony_ci}
4104514f5e3Sopenharmony_ci
4114514f5e3Sopenharmony_civoid ElfReader::SeparateSymtabSections(BinaryBufferParser &parser,
4124514f5e3Sopenharmony_ci                                       std::vector<ModuleSectionDes> &des,
4134514f5e3Sopenharmony_ci                                       const uintptr_t &secAddr,
4144514f5e3Sopenharmony_ci                                       llvm::ELF::Elf64_Off &secOffset,
4154514f5e3Sopenharmony_ci                                       const llvm::ELF::Elf64_Off &curShOffset)
4164514f5e3Sopenharmony_ci{
4174514f5e3Sopenharmony_ci    for (size_t i = 0; i < des.size(); ++i) {
4184514f5e3Sopenharmony_ci        auto moduleInfo = moduleInfo_[i];
4194514f5e3Sopenharmony_ci        uint32_t symtabSize = moduleInfo.symtabSize;
4204514f5e3Sopenharmony_ci        parser.ParseBuffer(reinterpret_cast<void *>(secAddr + secOffset), symtabSize, curShOffset + secOffset);
4214514f5e3Sopenharmony_ci        des[i].SetSecAddrAndSize(ElfSecName::SYMTAB, secAddr + secOffset, symtabSize);
4224514f5e3Sopenharmony_ci        secOffset += symtabSize;
4234514f5e3Sopenharmony_ci    }
4244514f5e3Sopenharmony_ci}
4254514f5e3Sopenharmony_ci}  // namespace panda::ecmascript
426