14514f5e3Sopenharmony_ci/* 24514f5e3Sopenharmony_ci * Copyright (c) 2024 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/dfx/dump_code/jit_dump_elf.h" 174514f5e3Sopenharmony_ci 184514f5e3Sopenharmony_cinamespace panda::ecmascript { 194514f5e3Sopenharmony_ci 204514f5e3Sopenharmony_civoid JsJitDumpElf::Initx86ElfHeader() 214514f5e3Sopenharmony_ci{ 224514f5e3Sopenharmony_ci header.e_ident[EI_MAG0] = ELFMAG0; 234514f5e3Sopenharmony_ci header.e_ident[EI_MAG1] = ELFMAG1; 244514f5e3Sopenharmony_ci header.e_ident[EI_MAG2] = ELFMAG2; 254514f5e3Sopenharmony_ci header.e_ident[EI_MAG3] = ELFMAG3; 264514f5e3Sopenharmony_ci header.e_ident[EI_CLASS] = ELFCLASS64; 274514f5e3Sopenharmony_ci header.e_ident[EI_DATA] = ELFDATA2LSB; 284514f5e3Sopenharmony_ci header.e_ident[EI_VERSION] = EV_CURRENT; 294514f5e3Sopenharmony_ci header.e_ident[EI_OSABI] = ELFOSABI_NONE; /* ELFOSABI_NONE represents UNIX System V */ 304514f5e3Sopenharmony_ci header.e_ident[EI_ABIVERSION] = 0; 314514f5e3Sopenharmony_ci (void)std::fill_n(&header.e_ident[EI_PAD], EI_NIDENT - EI_PAD, 0); 324514f5e3Sopenharmony_ci header.e_type = ET_REL; 334514f5e3Sopenharmony_ci header.e_machine = EM_X86_64; 344514f5e3Sopenharmony_ci header.e_version = EV_CURRENT; 354514f5e3Sopenharmony_ci header.e_entry = 0; 364514f5e3Sopenharmony_ci header.e_phoff = 0; 374514f5e3Sopenharmony_ci header.e_shoff = 0; /* later get */ 384514f5e3Sopenharmony_ci header.e_flags = 0; /* The Intel architecture defines no flags; so this member contains zero. */ 394514f5e3Sopenharmony_ci header.e_ehsize = sizeof(maplebe::FileHeader); 404514f5e3Sopenharmony_ci header.e_phentsize = 0; 414514f5e3Sopenharmony_ci header.e_phnum = 0; 424514f5e3Sopenharmony_ci header.e_shentsize = sizeof(maplebe::SectionHeader); 434514f5e3Sopenharmony_ci header.e_shnum = static_cast<uint16>(sections.size()); 444514f5e3Sopenharmony_ci header.e_shstrndx = strTabSection->GetIndex(); 454514f5e3Sopenharmony_ci} 464514f5e3Sopenharmony_ci 474514f5e3Sopenharmony_civoid JsJitDumpElf::InitArmElfHeader() 484514f5e3Sopenharmony_ci{ 494514f5e3Sopenharmony_ci header.e_ident[EI_MAG0] = ELFMAG0; 504514f5e3Sopenharmony_ci header.e_ident[EI_MAG1] = ELFMAG1; 514514f5e3Sopenharmony_ci header.e_ident[EI_MAG2] = ELFMAG2; 524514f5e3Sopenharmony_ci header.e_ident[EI_MAG3] = ELFMAG3; 534514f5e3Sopenharmony_ci header.e_ident[EI_CLASS] = ELFCLASS64; 544514f5e3Sopenharmony_ci header.e_ident[EI_DATA] = ELFDATA2LSB; 554514f5e3Sopenharmony_ci header.e_ident[EI_VERSION] = EV_CURRENT; 564514f5e3Sopenharmony_ci header.e_ident[EI_OSABI] = ELFOSABI_LINUX; 574514f5e3Sopenharmony_ci header.e_ident[EI_ABIVERSION] = 0; 584514f5e3Sopenharmony_ci std::fill_n(&header.e_ident[EI_PAD], EI_NIDENT - EI_PAD, 0); 594514f5e3Sopenharmony_ci header.e_type = ET_REL; 604514f5e3Sopenharmony_ci header.e_version = 1; 614514f5e3Sopenharmony_ci header.e_machine = EM_AARCH64; 624514f5e3Sopenharmony_ci header.e_flags = 0; 634514f5e3Sopenharmony_ci header.e_entry = 0; 644514f5e3Sopenharmony_ci header.e_ehsize = sizeof(maplebe::FileHeader); 654514f5e3Sopenharmony_ci header.e_phentsize = sizeof(maplebe::SegmentHeader); 664514f5e3Sopenharmony_ci header.e_shentsize = sizeof(maplebe::SectionHeader); 674514f5e3Sopenharmony_ci header.e_shstrndx = strTabSection->GetIndex(); 684514f5e3Sopenharmony_ci header.e_shoff = 0; 694514f5e3Sopenharmony_ci header.e_phoff = 0; 704514f5e3Sopenharmony_ci header.e_shnum = sections.size(); 714514f5e3Sopenharmony_ci header.e_phnum = 0; 724514f5e3Sopenharmony_ci} 734514f5e3Sopenharmony_ci 744514f5e3Sopenharmony_civoid JsJitDumpElf::UpdateSectionOffset(Section §ion) 754514f5e3Sopenharmony_ci{ 764514f5e3Sopenharmony_ci if (section.GetType() != SHT_NOBITS) { 774514f5e3Sopenharmony_ci section.SetOffset(globalOffset); 784514f5e3Sopenharmony_ci } else { 794514f5e3Sopenharmony_ci section.SetOffset(0); 804514f5e3Sopenharmony_ci } 814514f5e3Sopenharmony_ci} 824514f5e3Sopenharmony_ci 834514f5e3Sopenharmony_civoid JsJitDumpElf::UpdateGlobalOffset(Section §ion) 844514f5e3Sopenharmony_ci{ 854514f5e3Sopenharmony_ci if (section.GetType() != SHT_NOBITS) { 864514f5e3Sopenharmony_ci globalOffset += section.GetSectionSize(); 874514f5e3Sopenharmony_ci } 884514f5e3Sopenharmony_ci} 894514f5e3Sopenharmony_ci 904514f5e3Sopenharmony_civoid JsJitDumpElf::LayoutSections() 914514f5e3Sopenharmony_ci{ 924514f5e3Sopenharmony_ci globalOffset = sizeof(maplebe::FileHeader); 934514f5e3Sopenharmony_ci globalOffset = Alignment::Align<maplebe::Offset>(globalOffset, k8Bits); 944514f5e3Sopenharmony_ci 954514f5e3Sopenharmony_ci for (auto *section : sections) { 964514f5e3Sopenharmony_ci section->SetSectionHeaderNameIndex(static_cast<maplebe::Word>(strTabSection->AddString(section->GetName()))); 974514f5e3Sopenharmony_ci } 984514f5e3Sopenharmony_ci 994514f5e3Sopenharmony_ci for (auto *section : sections) { 1004514f5e3Sopenharmony_ci globalOffset = Alignment::Align<maplebe::Offset>(globalOffset, section->GetAlign()); 1014514f5e3Sopenharmony_ci /* lay out section */ 1024514f5e3Sopenharmony_ci UpdateSectionOffset(*section); 1034514f5e3Sopenharmony_ci if (section->GetType() != SHT_NOBITS) { 1044514f5e3Sopenharmony_ci section->GenerateData(); 1054514f5e3Sopenharmony_ci } 1064514f5e3Sopenharmony_ci UpdateGlobalOffset(*section); 1074514f5e3Sopenharmony_ci } 1084514f5e3Sopenharmony_ci 1094514f5e3Sopenharmony_ci globalOffset = Alignment::Align<maplebe::Offset>(globalOffset, 16U); 1104514f5e3Sopenharmony_ci header.e_shoff = globalOffset; 1114514f5e3Sopenharmony_ci header.e_shnum = static_cast<uint16>(sections.size()); 1124514f5e3Sopenharmony_ci} 1134514f5e3Sopenharmony_ci 1144514f5e3Sopenharmony_civoid JsJitDumpElf::RegisterSection(Section §ion) 1154514f5e3Sopenharmony_ci{ 1164514f5e3Sopenharmony_ci sections.push_back(§ion); 1174514f5e3Sopenharmony_ci section.SetIndex(static_cast<maplebe::SectionIndex>(sections.size() - 1)); 1184514f5e3Sopenharmony_ci} 1194514f5e3Sopenharmony_ci 1204514f5e3Sopenharmony_civoid JsJitDumpElf::Init() 1214514f5e3Sopenharmony_ci{ 1224514f5e3Sopenharmony_ci DataSection *nullDataSection = new DataSection(" ", SHT_NULL, 0, 0); 1234514f5e3Sopenharmony_ci RegisterSection(*nullDataSection); 1244514f5e3Sopenharmony_ci strTabSection = new StringSection(".strtab", SHT_STRTAB, 0, 1); 1254514f5e3Sopenharmony_ci RegisterSection(*strTabSection); 1264514f5e3Sopenharmony_ci textSection = new DataSection(".text", SHT_PROGBITS, SHF_ALLOC | SHF_EXECINSTR, k8Bits); 1274514f5e3Sopenharmony_ci RegisterSection(*textSection); 1284514f5e3Sopenharmony_ci symbolTabSection = new SymbolSection(".symtab", SHT_SYMTAB, 0, k8Bits, *strTabSection); 1294514f5e3Sopenharmony_ci RegisterSection(*symbolTabSection); 1304514f5e3Sopenharmony_ci} 1314514f5e3Sopenharmony_ci 1324514f5e3Sopenharmony_civoid JsJitDumpElf::AppendData(std::vector<uint8> &codeBuff) 1334514f5e3Sopenharmony_ci{ 1344514f5e3Sopenharmony_ci textSection->AppendData(codeBuff.data(), codeBuff.size()); 1354514f5e3Sopenharmony_ci} 1364514f5e3Sopenharmony_ci 1374514f5e3Sopenharmony_civoid JsJitDumpElf::AddSymToSymTab(const maplebe::Symbol &symbol, int64 symIdx) 1384514f5e3Sopenharmony_ci{ 1394514f5e3Sopenharmony_ci localSymTab.push_back(std::make_pair(symbol, symIdx)); 1404514f5e3Sopenharmony_ci} 1414514f5e3Sopenharmony_ci 1424514f5e3Sopenharmony_civoid JsJitDumpElf::AppendGlobalSymsToSymTabSec() 1434514f5e3Sopenharmony_ci{ 1444514f5e3Sopenharmony_ci for (auto elem : localSymTab) { 1454514f5e3Sopenharmony_ci const maplebe::Symbol &symbol = elem.first; 1464514f5e3Sopenharmony_ci int64 symIdx = elem.second; 1474514f5e3Sopenharmony_ci symbolTabSection->AppendSymbol(symbol); 1484514f5e3Sopenharmony_ci symbolTabSection->AppendIdxInSymbols(symIdx); 1494514f5e3Sopenharmony_ci } 1504514f5e3Sopenharmony_ci} 1514514f5e3Sopenharmony_ci 1524514f5e3Sopenharmony_civoid JsJitDumpElf::AppendSymbolToSymTab(int64 symIdx, uint64 funcSymValue, uint64 funcSymSize, 1534514f5e3Sopenharmony_ci const std::string &symbolName) 1544514f5e3Sopenharmony_ci{ 1554514f5e3Sopenharmony_ci uint8 funcSymType = STB_GLOBAL; 1564514f5e3Sopenharmony_ci auto nameIndex = strTabSection->AddString(symbolName); 1574514f5e3Sopenharmony_ci AddSymToSymTab({static_cast<maplebe::Word>(nameIndex), 1584514f5e3Sopenharmony_ci static_cast<uint8>((funcSymType << kLeftShift4Bits) + (STT_FUNC & 0xf)), 0, textSection->GetIndex(), 1594514f5e3Sopenharmony_ci funcSymValue, funcSymSize}, symIdx); 1604514f5e3Sopenharmony_ci} 1614514f5e3Sopenharmony_ci 1624514f5e3Sopenharmony_civoid JsJitDumpElf::SetFileOffset(int fd, uint64 offset) 1634514f5e3Sopenharmony_ci{ 1644514f5e3Sopenharmony_ci lseek(fd, offset, SEEK_SET); 1654514f5e3Sopenharmony_ci} 1664514f5e3Sopenharmony_ci 1674514f5e3Sopenharmony_civoid JsJitDumpElf::WriteJitElfFile(int fd) 1684514f5e3Sopenharmony_ci{ 1694514f5e3Sopenharmony_ci AppendGlobalSymsToSymTabSec(); 1704514f5e3Sopenharmony_ci /* Init elf file header */ 1714514f5e3Sopenharmony_ci InitArmElfHeader(); 1724514f5e3Sopenharmony_ci LayoutSections(); 1734514f5e3Sopenharmony_ci /* write header */ 1744514f5e3Sopenharmony_ci (void)write(fd, reinterpret_cast<const char *>(&header), sizeof(header)); 1754514f5e3Sopenharmony_ci /* write sections */ 1764514f5e3Sopenharmony_ci for (auto *section : sections) { 1774514f5e3Sopenharmony_ci if (section->GetType() == SHT_NOBITS) { 1784514f5e3Sopenharmony_ci continue; 1794514f5e3Sopenharmony_ci } 1804514f5e3Sopenharmony_ci SetFileOffset(fd, section->GetOffset()); 1814514f5e3Sopenharmony_ci section->WriteSection(fd); 1824514f5e3Sopenharmony_ci } 1834514f5e3Sopenharmony_ci SetFileOffset(fd, header.e_shoff); 1844514f5e3Sopenharmony_ci /* write section table */ 1854514f5e3Sopenharmony_ci for (auto *section : sections) { 1864514f5e3Sopenharmony_ci (void)write(fd, §ion->GetSectionHeader(), sizeof(section->GetSectionHeader())); 1874514f5e3Sopenharmony_ci } 1884514f5e3Sopenharmony_ci} 1894514f5e3Sopenharmony_ci 1904514f5e3Sopenharmony_civoid JsJitDumpElf::ClearData() 1914514f5e3Sopenharmony_ci{ 1924514f5e3Sopenharmony_ci localSymTab.clear(); 1934514f5e3Sopenharmony_ci globalOffset = 0; 1944514f5e3Sopenharmony_ci textSection->ClearData(); 1954514f5e3Sopenharmony_ci symbolTabSection->ClearData(); 1964514f5e3Sopenharmony_ci strTabSection->ClearData(); 1974514f5e3Sopenharmony_ci sections.clear(); 1984514f5e3Sopenharmony_ci} 1994514f5e3Sopenharmony_ci 2004514f5e3Sopenharmony_ci} // namespace panda::ecmascript 201