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/stub_file_info.h" 174514f5e3Sopenharmony_ci#include "ecmascript/compiler/aot_file/elf_builder.h" 184514f5e3Sopenharmony_ci#include "ecmascript/compiler/aot_file/elf_reader.h" 194514f5e3Sopenharmony_ci 204514f5e3Sopenharmony_ci#ifndef PANDA_TARGET_OHOS 214514f5e3Sopenharmony_ciextern const uint8_t _binary_stub_an_start[]; 224514f5e3Sopenharmony_ciextern const uint32_t _binary_stub_an_length; 234514f5e3Sopenharmony_ci#endif 244514f5e3Sopenharmony_ci 254514f5e3Sopenharmony_cinamespace panda::ecmascript { 264514f5e3Sopenharmony_civoid StubFileInfo::Save(const std::string &filename, Triple triple) 274514f5e3Sopenharmony_ci{ 284514f5e3Sopenharmony_ci std::string realPath; 294514f5e3Sopenharmony_ci if (!RealPath(filename, realPath, false)) { 304514f5e3Sopenharmony_ci return; 314514f5e3Sopenharmony_ci } 324514f5e3Sopenharmony_ci 334514f5e3Sopenharmony_ci std::ofstream file(realPath.c_str(), std::ofstream::binary); 344514f5e3Sopenharmony_ci ASSERT(GetCodeUnitsNum() == ASMSTUB_MODULE_NUM); 354514f5e3Sopenharmony_ci SetStubNum(entries_.size()); 364514f5e3Sopenharmony_ci ModuleSectionDes &des = des_[0]; 374514f5e3Sopenharmony_ci size_t lastModuleSectionIdx = ASMSTUB_MODULE_NUM - 1; 384514f5e3Sopenharmony_ci // add section 394514f5e3Sopenharmony_ci uint64_t funcEntryAddr = reinterpret_cast<uint64_t>(entries_.data()); 404514f5e3Sopenharmony_ci uint32_t funcEntrySize = sizeof(FuncEntryDes) * entryNum_; 414514f5e3Sopenharmony_ci des.SetSecAddrAndSize(ElfSecName::ARK_FUNCENTRY, funcEntryAddr, funcEntrySize); 424514f5e3Sopenharmony_ci uint64_t asmStubAddr = GetAsmStubAddr(); 434514f5e3Sopenharmony_ci uint32_t asmStubSize = GetAsmStubSize(); 444514f5e3Sopenharmony_ci des.SetSecAddrAndSize(ElfSecName::ARK_ASMSTUB, asmStubAddr, asmStubSize); 454514f5e3Sopenharmony_ci std::vector<uint32_t> moduleInfo = {1}; 464514f5e3Sopenharmony_ci uint64_t secSizeInfoAddr = reinterpret_cast<uint64_t>(moduleInfo.data()); 474514f5e3Sopenharmony_ci des.SetSecAddrAndSize(ElfSecName::ARK_MODULEINFO, secSizeInfoAddr, sizeof(uint32_t)); 484514f5e3Sopenharmony_ci des_[lastModuleSectionIdx].AddAsmStubELFInfo(asmStubELFInfo_); 494514f5e3Sopenharmony_ci 504514f5e3Sopenharmony_ci ElfBuilder builder(des_, GetDumpSectionNames()); 514514f5e3Sopenharmony_ci llvm::ELF::Elf64_Ehdr header; 524514f5e3Sopenharmony_ci builder.PackELFHeader(header, base::FileHeaderBase::ToVersionNumber(AOTFileVersion::AN_VERSION), triple); 534514f5e3Sopenharmony_ci file.write(reinterpret_cast<char *>(&header), sizeof(llvm::ELF::Elf64_Ehdr)); 544514f5e3Sopenharmony_ci builder.PackELFSections(file); 554514f5e3Sopenharmony_ci builder.PackELFSegment(file); 564514f5e3Sopenharmony_ci file.close(); 574514f5e3Sopenharmony_ci} 584514f5e3Sopenharmony_ci 594514f5e3Sopenharmony_cibool StubFileInfo::MmapLoad(const std::string &fileName) 604514f5e3Sopenharmony_ci{ 614514f5e3Sopenharmony_ci std::string filename = fileName.empty() ? STUB_AN_FILE : fileName; 624514f5e3Sopenharmony_ci std::string realPath; 634514f5e3Sopenharmony_ci if (!RealPath(filename, realPath, false)) { 644514f5e3Sopenharmony_ci LOG_COMPILER(ERROR) << "Can not load stub file from path [ " << filename << " ], " 654514f5e3Sopenharmony_ci << "please execute ark_stub_compiler with options --stub-file."; 664514f5e3Sopenharmony_ci return false; 674514f5e3Sopenharmony_ci } 684514f5e3Sopenharmony_ci 694514f5e3Sopenharmony_ci if (!FileExist(realPath.c_str())) { 704514f5e3Sopenharmony_ci LOG_ECMA(WARN) << "File not exist. file: " << realPath; 714514f5e3Sopenharmony_ci return false; 724514f5e3Sopenharmony_ci } 734514f5e3Sopenharmony_ci 744514f5e3Sopenharmony_ci fileMapMem_ = FileMap(realPath.c_str(), FILE_RDONLY, PAGE_PROT_READ); 754514f5e3Sopenharmony_ci if (fileMapMem_.GetOriginAddr() == nullptr) { 764514f5e3Sopenharmony_ci LOG_ECMA(ERROR) << "File mmap failed"; 774514f5e3Sopenharmony_ci return false; 784514f5e3Sopenharmony_ci } 794514f5e3Sopenharmony_ci 804514f5e3Sopenharmony_ci ElfReader reader(fileMapMem_); 814514f5e3Sopenharmony_ci std::vector<ElfSecName> secs = GetDumpSectionNames(); 824514f5e3Sopenharmony_ci reader.ParseELFSections(des_, secs); 834514f5e3Sopenharmony_ci moduleNum_ = des_.size(); 844514f5e3Sopenharmony_ci ASSERT(moduleNum_ == ASMSTUB_MODULE_NUM); 854514f5e3Sopenharmony_ci 864514f5e3Sopenharmony_ci if (!reader.ParseELFSegment()) { 874514f5e3Sopenharmony_ci LOG_ECMA(ERROR) << "modify mmap area permission failed"; 884514f5e3Sopenharmony_ci return false; 894514f5e3Sopenharmony_ci } 904514f5e3Sopenharmony_ci 914514f5e3Sopenharmony_ci ModuleSectionDes &des = des_[0]; 924514f5e3Sopenharmony_ci uint64_t funcEntryAddr = des.GetSecAddr(ElfSecName::ARK_FUNCENTRY); 934514f5e3Sopenharmony_ci uint32_t funcEntrySize = des.GetSecSize(ElfSecName::ARK_FUNCENTRY); 944514f5e3Sopenharmony_ci FuncEntryDes *entryDes = reinterpret_cast<FuncEntryDes *>(funcEntryAddr); 954514f5e3Sopenharmony_ci entryNum_ = funcEntrySize / sizeof(FuncEntryDes); 964514f5e3Sopenharmony_ci entries_.assign(entryDes, entryDes + entryNum_); 974514f5e3Sopenharmony_ci uint64_t asmStubAddr = des.GetSecAddr(ElfSecName::ARK_ASMSTUB); 984514f5e3Sopenharmony_ci uint32_t asmStubSize = des.GetSecSize(ElfSecName::ARK_ASMSTUB); 994514f5e3Sopenharmony_ci SetAsmStubAddr(asmStubAddr); 1004514f5e3Sopenharmony_ci SetAsmStubSize(asmStubSize); 1014514f5e3Sopenharmony_ci 1024514f5e3Sopenharmony_ci for (auto &entry : entries_) { 1034514f5e3Sopenharmony_ci if (entry.IsGeneralRTStub()) { 1044514f5e3Sopenharmony_ci uint64_t begin = GetAsmStubAddr(); 1054514f5e3Sopenharmony_ci entry.codeAddr_ += begin; 1064514f5e3Sopenharmony_ci } else { 1074514f5e3Sopenharmony_ci auto moduleDes = des_[entry.moduleIndex_]; 1084514f5e3Sopenharmony_ci entry.codeAddr_ += moduleDes.GetSecAddr(ElfSecName::TEXT); 1094514f5e3Sopenharmony_ci } 1104514f5e3Sopenharmony_ci } 1114514f5e3Sopenharmony_ci LOG_COMPILER(INFO) << "loaded stub file successfully"; 1124514f5e3Sopenharmony_ci return true; 1134514f5e3Sopenharmony_ci} 1144514f5e3Sopenharmony_ci#ifndef PANDA_TARGET_OHOS 1154514f5e3Sopenharmony_cibool StubFileInfo::Load() 1164514f5e3Sopenharmony_ci{ 1174514f5e3Sopenharmony_ci if (_binary_stub_an_length <= 1) { 1184514f5e3Sopenharmony_ci LOG_FULL(FATAL) << "stub.an length <= 1, is default and invalid."; 1194514f5e3Sopenharmony_ci return false; 1204514f5e3Sopenharmony_ci } 1214514f5e3Sopenharmony_ci 1224514f5e3Sopenharmony_ci BinaryBufferParser binBufparser(const_cast<uint8_t *>(_binary_stub_an_start), _binary_stub_an_length); 1234514f5e3Sopenharmony_ci moduleNum_ = ASMSTUB_MODULE_NUM; 1244514f5e3Sopenharmony_ci des_.resize(moduleNum_); 1254514f5e3Sopenharmony_ci 1264514f5e3Sopenharmony_ci ExecutedMemoryAllocator::AllocateBuf(_binary_stub_an_length, stubsMem_, PAGE_PROT_READWRITE); 1274514f5e3Sopenharmony_ci 1284514f5e3Sopenharmony_ci ElfReader reader(stubsMem_); 1294514f5e3Sopenharmony_ci std::vector<ElfSecName> secs = GetDumpSectionNames(); 1304514f5e3Sopenharmony_ci reader.ParseELFSections(binBufparser, des_, secs); 1314514f5e3Sopenharmony_ci 1324514f5e3Sopenharmony_ci ModuleSectionDes &des = des_[0]; 1334514f5e3Sopenharmony_ci uint64_t funcEntryAddr = des.GetSecAddr(ElfSecName::ARK_FUNCENTRY); 1344514f5e3Sopenharmony_ci uint32_t funcEntrySize = des.GetSecSize(ElfSecName::ARK_FUNCENTRY); 1354514f5e3Sopenharmony_ci FuncEntryDes *entryDes = reinterpret_cast<FuncEntryDes *>(funcEntryAddr); 1364514f5e3Sopenharmony_ci entryNum_ = funcEntrySize / sizeof(FuncEntryDes); 1374514f5e3Sopenharmony_ci entries_.assign(entryDes, entryDes + entryNum_); 1384514f5e3Sopenharmony_ci uint64_t asmStubAddr = des.GetSecAddr(ElfSecName::ARK_ASMSTUB); 1394514f5e3Sopenharmony_ci uint32_t asmStubSize = des.GetSecSize(ElfSecName::ARK_ASMSTUB); 1404514f5e3Sopenharmony_ci SetAsmStubAddr(asmStubAddr); 1414514f5e3Sopenharmony_ci SetAsmStubSize(asmStubSize); 1424514f5e3Sopenharmony_ci 1434514f5e3Sopenharmony_ci for (auto &entry : entries_) { 1444514f5e3Sopenharmony_ci if (entry.IsGeneralRTStub()) { 1454514f5e3Sopenharmony_ci uint64_t begin = GetAsmStubAddr(); 1464514f5e3Sopenharmony_ci entry.codeAddr_ += begin; 1474514f5e3Sopenharmony_ci } else { 1484514f5e3Sopenharmony_ci auto moduleDes = des_[entry.moduleIndex_]; 1494514f5e3Sopenharmony_ci entry.codeAddr_ += moduleDes.GetSecAddr(ElfSecName::TEXT); 1504514f5e3Sopenharmony_ci } 1514514f5e3Sopenharmony_ci } 1524514f5e3Sopenharmony_ci LOG_COMPILER(INFO) << "loaded stub file successfully"; 1534514f5e3Sopenharmony_ci if (!PageProtect(stubsMem_.addr_, stubsMem_.size_, PAGE_PROT_EXEC_READ)) { 1544514f5e3Sopenharmony_ci return false; 1554514f5e3Sopenharmony_ci } 1564514f5e3Sopenharmony_ci return true; 1574514f5e3Sopenharmony_ci} 1584514f5e3Sopenharmony_ci#endif 1594514f5e3Sopenharmony_ciconst std::vector<ElfSecName> &StubFileInfo::GetDumpSectionNames() 1604514f5e3Sopenharmony_ci{ 1614514f5e3Sopenharmony_ci static const std::vector<ElfSecName> secNames = { 1624514f5e3Sopenharmony_ci ElfSecName::TEXT, 1634514f5e3Sopenharmony_ci ElfSecName::STRTAB, 1644514f5e3Sopenharmony_ci ElfSecName::SYMTAB, 1654514f5e3Sopenharmony_ci ElfSecName::SHSTRTAB, 1664514f5e3Sopenharmony_ci ElfSecName::ARK_STACKMAP, 1674514f5e3Sopenharmony_ci ElfSecName::ARK_FUNCENTRY, 1684514f5e3Sopenharmony_ci ElfSecName::ARK_ASMSTUB, 1694514f5e3Sopenharmony_ci ElfSecName::ARK_MODULEINFO 1704514f5e3Sopenharmony_ci }; 1714514f5e3Sopenharmony_ci return secNames; 1724514f5e3Sopenharmony_ci} 1734514f5e3Sopenharmony_ci 1744514f5e3Sopenharmony_civoid StubFileInfo::Dump() const 1754514f5e3Sopenharmony_ci{ 1764514f5e3Sopenharmony_ci uint64_t asmAddr = GetAsmStubAddr(); 1774514f5e3Sopenharmony_ci uint64_t asmSize = GetAsmStubSize(); 1784514f5e3Sopenharmony_ci 1794514f5e3Sopenharmony_ci LOG_COMPILER(ERROR) << "Stub file loading: "; 1804514f5e3Sopenharmony_ci LOG_COMPILER(ERROR) << " - asm stubs [0x" << std::hex << asmAddr << ", 0x" << std::hex << asmAddr + asmSize << "]"; 1814514f5e3Sopenharmony_ci 1824514f5e3Sopenharmony_ci for (const ModuleSectionDes &d : des_) { 1834514f5e3Sopenharmony_ci for (const auto &s : d.GetSectionsInfo()) { 1844514f5e3Sopenharmony_ci std::string name = d.GetSecName(s.first); 1854514f5e3Sopenharmony_ci uint32_t size = d.GetSecSize(s.first); 1864514f5e3Sopenharmony_ci uint64_t addr = d.GetSecAddr(s.first); 1874514f5e3Sopenharmony_ci LOG_COMPILER(ERROR) << " - section = " << name << " [0x" << std::hex << addr << ", 0x" << std::hex 1884514f5e3Sopenharmony_ci << addr + size << "]"; 1894514f5e3Sopenharmony_ci } 1904514f5e3Sopenharmony_ci } 1914514f5e3Sopenharmony_ci} 1924514f5e3Sopenharmony_ci} // namespace panda::ecmascript 193