Standardize the ELF format of the Stub File

Issue:https://gitee.com/openharmony/arkcompiler_ets_runtime/issues/I6WNMU

Signed-off-by: wuzhangda <wuzhangda@huawei.com>
Change-Id: Ie2f8d692e5b2ad2361876dc29e1592577f643247
This commit is contained in:
wuzhangda 2023-04-18 11:50:29 +08:00
parent f9a8b44397
commit 4a7cd90fa0
14 changed files with 776 additions and 363 deletions

View File

@ -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",

View File

@ -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<uint64_t>(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<uint64_t>(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<char *>(&header), sizeof(llvm::ELF::Elf64_Shdr));
builder.PackELFSections(file);
builder.PackELFHeader(header, base::FileHeader::ToVersionNumber(AOTFileVersion::AN_VERSION), triple);
file.write(reinterpret_cast<char *>(&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<ElfSecName> 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;
}
@ -121,8 +115,8 @@ void AnFileInfo::RelocateTextSection()
const std::vector<ElfSecName> &AnFileInfo::GetDumpSectionNames()
{
static const std::vector<ElfSecName> secNames = {ElfSecName::RODATA_CST8, ElfSecName::TEXT,
ElfSecName::STRTAB, ElfSecName::SYMTAB,
ElfSecName::ARK_STACKMAP, ElfSecName::ARK_FUNCENTRY};
ElfSecName::STRTAB, ElfSecName::ARK_STACKMAP,
ElfSecName::ARK_FUNCENTRY};
return secNames;
}

View File

@ -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_) {

View File

@ -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};

View File

@ -21,48 +21,20 @@
namespace panda::ecmascript {
void ElfBuilder::ModifyStrTabSection()
{
bool existedStrTab = false;
uint64_t strTabAddr = 0;
uint32_t strTabSize = 0;
std::vector<std::string> sectionNames;
std::map<ElfSecName, std::pair<uint64_t, uint32_t>> &sections = sectionDes_.GetSectionsInfo();
// modify strtab
for (auto &s : sections) {
if (s.first == ElfSecName::STRTAB) {
existedStrTab = true;
strTabAddr = s.second.first;
strTabSize = s.second.second;
break;
}
}
std::map<ElfSecName, std::pair<uint64_t, uint32_t>> &sections = des_[0].GetSectionsInfo();
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<llvm::ELF::Elf64_Word>(-1)) {
sectionNames.emplace_back(str);
}
}
uint32_t size = 0;
if (existedStrTab) {
size += strTabSize;
}
for (auto &str: sectionNames) {
uint32_t size = 1;
for (auto &s : sections_) {
std::string str = ModuleSectionDes::GetSecName(s);
size = size + str.size() + 1;
}
strTabPtr_ = std::make_unique<char []>(size);
char *dst = strTabPtr_.get();
if (strTabSize > 0) {
if ((memcpy_s(dst, size, reinterpret_cast<char *>(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<uint64_t>(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<ElfSecName, std::pair<uint64_t, uint32_t>> &sections = sectionDes_.GetSectionsInfo();
const std::map<ElfSecName, std::pair<uint64_t, uint32_t>> &sections = 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<ElfSecName, std::pair<uint64_t, uint32_t>> &sections = sectionDes_.GetSectionsInfo();
std::shared_ptr<uint8_t> ptr = sectionDes_.GetArkStackMapSharePtr();
for (auto &des : des_) {
std::map<ElfSecName, std::pair<uint64_t, uint32_t>> &sections = des.GetSectionsInfo();
std::shared_ptr<uint8_t> ptr = des.GetArkStackMapSharePtr();
uint64_t arkStackMapAddr = reinterpret_cast<uint64_t>(ptr.get());
uint32_t arkStackMapSize = sectionDes_.GetArkStackMapSize();
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<ModuleSectionDes> &des,
const std::vector<ElfSecName> &sections): 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<ElfSecName, std::pair<uint64_t, uint32_t>> &sections = 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<ElfSecName, std::pair<uint64_t, uint32_t>>& 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<ElfSecName> 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;
idx++;
}
shstrndx++;
}
UNREACHABLE();
}
llvm::ELF::Elf64_Half ElfBuilder::GetSecSize() const
{
llvm::ELF::Elf64_Half secsSize = 0;
const std::map<ElfSecName, std::pair<uint64_t, uint32_t>> &sections = 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<ElfSecName, std::pair<uint64_t, uint32_t>> &sections = 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<ElfSecName, std::pair<uint64_t, uint32_t>> &sections = 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<llvm::ELF::Elf64_Half>(GetShIndex(ElfSecName::STRTAB));
// section header stub sec info index
header.e_flags = static_cast<llvm::ELF::Elf64_Word>(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<ElfSecName, std::pair<uint64_t, uint32_t>> &sections = sectionDes_.GetSectionsInfo();
const std::map<ElfSecName, std::pair<uint64_t, uint32_t>> &sections = GetCurrentSecInfo();
std::set<ElfSecName> 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<ElfSecName, std::pair<uint64_t, uint32_t>> &sections = sectionDes_.GetSectionsInfo();
const std::map<ElfSecName, std::pair<uint64_t, uint32_t>> &sections = 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<int>(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<uint64_t, uint32_t> ElfBuilder::FindStrTab() const
{
const std::map<ElfSecName, std::pair<uint64_t, uint32_t>> &sections = sectionDes_.GetSectionsInfo();
const std::map<ElfSecName, std::pair<uint64_t, uint32_t>> &sections = 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<uint64_t, uint32_t> 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<llvm::ELF::Elf64_Shdr []> &shdr, const uint32_t &secNum)
{
std::map<ElfSecName, std::pair<uint64_t, uint32_t>> &sections = sectionDes_.GetSectionsInfo();
uint32_t secNum = sections.size() + 1; // 1 : section id = 0 is null section
std::unique_ptr<llvm::ELF::Elf64_Shdr []> shdr = std::make_unique<llvm::ELF::Elf64_Shdr []>(secNum);
if (memset_s(reinterpret_cast<void *>(&shdr[0]), sizeof(llvm::ELF::Elf64_Shdr), 0, sizeof(llvm::ELF::Elf64_Shdr)) != EOK) {
shdr = std::make_unique<llvm::ELF::Elf64_Shdr []>(secNum);
if (memset_s(reinterpret_cast<void *>(&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<ModuleSectionDes::ModuleRegionInfo> &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<char *>(rodataAddr), rodataSize);
curInfo.rodataSize = rodataSize;
curSecOffset += rodataSize;
}
curInfo.textSize = curSecSize;
file.write(reinterpret_cast<char *>(curSecAddr), curSecSize);
curSecOffset += curSecSize;
}
}
void ElfBuilder::MergeArkStackMapSections(std::ofstream &file,
std::vector<ModuleSectionDes::ModuleRegionInfo> &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<char *>(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<ElfSecName, std::pair<uint64_t, uint32_t>> &sections = GetCurrentSecInfo();
uint32_t secNum = sections.size() + 1; // 1 : section id = 0 is null section
std::unique_ptr<llvm::ELF::Elf64_Shdr []> 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);
curShdr.sh_addralign = sectionToAlign_[secName];
curSecOffset = AlignUp(curSecOffset, curShdr.sh_addralign);
file.seekp(curSecOffset);
}
auto it = sectionToSegment_.find(s.first);
ASSERT(it != sectionToSegment_.end());
ElfSecName segName = it->second;
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<uint8_t>(file.tellp());
uint32_t curSecSize = GetCurrentDes().GetSecSize(secName);
uint64_t curSecAddr = GetCurrentDes().GetSecAddr(secName);
std::string secNameStr = ModuleSectionDes::GetSecName(secName);
sectionToFileOffset_[secName] = static_cast<uint8_t>(file.tellp());
file.write(reinterpret_cast<char *>(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<llvm::ELF::Elf64_Word>(-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<uint32_t>(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<ElfSecName, std::pair<uint64_t, uint32_t>> &sections = GetCurrentSecInfo();
uint32_t secNum = sections.size() + 1; // 1 : section id = 0 is null section
std::unique_ptr<llvm::ELF::Elf64_Shdr []> shdr;
AllocateShdr(shdr, secNum);
std::vector<ModuleSectionDes::ModuleRegionInfo> 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<llvm::ELF::Elf64_Word>(-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<char *>(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<char *>(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<char *>(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<ElfSecName, llvm::ELF::Elf64_Off> segmentToMaxAddress;
std::set<ElfSecName> segments;
// SecName -> addr & size
std::map<ElfSecName, std::pair<uint64_t, uint32_t>> &sections = sectionDes_.GetSectionsInfo();
const std::map<ElfSecName, std::pair<uint64_t, uint32_t>> &sections = GetCurrentSecInfo();
llvm::ELF::Elf64_Off offset = e_phoff;
for (auto &s: sections) {
ElfSection section = ElfSection(s.first);

View File

@ -30,38 +30,58 @@ class ModuleSectionDes;
class ElfBuilder {
public:
ElfBuilder(ModuleSectionDes sectionDes);
ElfBuilder(const std::vector<ModuleSectionDes> &des, const std::vector<ElfSecName> &sections);
~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<ModuleSectionDes::ModuleRegionInfo> &moduleInfo, llvm::ELF::Elf64_Off &curSecOffset);
void MergeArkStackMapSections(std::ofstream &elfFile,
std::vector<ModuleSectionDes::ModuleRegionInfo> &moduleInfo, llvm::ELF::Elf64_Off &curSecOffset);
static llvm::ELF::Elf64_Word FindShName(std::string name, uintptr_t strTabPtr, int strTabSize);
std::map<ElfSecName, std::pair<uint64_t, uint32_t>> 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<ElfSecName, std::pair<uint64_t, uint32_t>> &sections) 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<uint64_t, uint32_t> FindStrTab() const;
void AllocateShdr(std::unique_ptr<llvm::ELF::Elf64_Shdr []> &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<ModuleSectionDes> des_ {};
std::unique_ptr<char []> strTabPtr_ {nullptr};
std::map<ElfSecName, llvm::ELF::Elf64_Shdr> sectionToShdr_;
std::map<ElfSecName, llvm::ELF::Elf64_Xword> sectionToAlign_;
std::map<ElfSecName, ElfSecName> sectionToSegment_;
std::map<ElfSecName, uintptr_t> sectionToFileOffset_;
std::map<ElfSecName, unsigned> segmentToFlag_;
std::vector<ElfSecName> sections_ {};
std::set<ElfSecName> segments_;
bool enableSecDump_ {false};
};

View File

@ -43,6 +43,7 @@ void ElfReader::ParseELFSections(ModuleSectionDes &des, std::vector<ElfSecName>
llvm::ELF::Elf64_Ehdr *ehdr = reinterpret_cast<llvm::ELF::Elf64_Ehdr *>(fileMapMem_.GetOriginAddr());
char *addr = reinterpret_cast<char *>(ehdr);
llvm::ELF::Elf64_Shdr *shdr = reinterpret_cast<llvm::ELF::Elf64_Shdr *>(addr + ehdr->e_shoff);
ASSERT(ehdr->e_shstrndx != static_cast<llvm::ELF::Elf64_Half>(-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<ElfSecName>
des.SetArkStackMapPtr(reinterpret_cast<uint8_t *>(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<uint64_t>(fileMapMem_.GetOriginAddr());
return *(reinterpret_cast<ModuleSectionDes::ModuleRegionInfo *>
(codeAddress + offset + i * sizeof(ModuleSectionDes::ModuleRegionInfo)));
}
void ElfReader::ParseELFSections(std::vector<ModuleSectionDes> &des, std::vector<ElfSecName> &secs)
{
ASSERT(des.size() == ASMSTUB_MODULE_NUM);
llvm::ELF::Elf64_Ehdr *ehdr = reinterpret_cast<llvm::ELF::Elf64_Ehdr *>(fileMapMem_.GetOriginAddr());
char *addr = reinterpret_cast<char *>(ehdr);
llvm::ELF::Elf64_Shdr *shdrs = reinterpret_cast<llvm::ELF::Elf64_Shdr *>(addr + ehdr->e_shoff);
ASSERT(ehdr->e_shstrndx != static_cast<llvm::ELF::Elf64_Half>(-1));
llvm::ELF::Elf64_Shdr strdr = shdrs[ehdr->e_shstrndx];
ASSERT(ehdr->e_flags != static_cast<llvm::ELF::Elf64_Word>(-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<ElfSecName> 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<char *>(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<uintptr_t>(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<uint32_t>(secOffset) == secSize);
break;
}
case ElfSecName::ARK_STACKMAP: {
llvm::ELF::Elf64_Off secOffset = 0;
SeparateArkStackMapSections(des, secAddr, secOffset, moduledr.sh_offset);
ASSERT(static_cast<uint32_t>(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<ModuleSectionDes> &des, std::vector<ElfSecName> &secs)
{
ASSERT(des.size() == ASMSTUB_MODULE_NUM);
uint64_t codeAddress = reinterpret_cast<uint64_t>(stubsMem_.addr_);
llvm::ELF::Elf64_Ehdr ehdr;
parser.ParseBuffer(&ehdr, sizeof(ehdr), 0);
std::vector<llvm::ELF::Elf64_Shdr> 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<llvm::ELF::Elf64_Half>(-1));
llvm::ELF::Elf64_Shdr strdr = shdrs[ehdr.e_shstrndx];
ASSERT(ehdr.e_flags != static_cast<llvm::ELF::Elf64_Word>(-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<ElfSecName> 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<char *>(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<uint64_t>(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<uint32_t>(secOffset) == secSize);
break;
}
case ElfSecName::ARK_STACKMAP: {
llvm::ELF::Elf64_Off secOffset = 0;
SeparateArkStackMapSections(parser, des, secAddr, secOffset, secShdr.sh_offset);
ASSERT(static_cast<uint32_t>(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<void *>(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<ModuleSectionDes> &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<ModuleSectionDes> &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<uint8_t *>(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<ModuleSectionDes> &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<void *>(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<void *>(secAddr + secOffset), textSize, curShOffset + secOffset);
des[i].SetSecAddrAndSize(ElfSecName::TEXT, secAddr + secOffset, textSize);
secOffset += textSize;
}
}
void ElfReader::SeparateArkStackMapSections(BinaryBufferParser &parser,
std::vector<ModuleSectionDes> &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<void *>(secAddr + secOffset), stackMapSize, curShOffset + secOffset);
des[i].SetArkStackMapPtr(reinterpret_cast<uint8_t *>(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

View File

@ -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<ElfSecName> &secs);
void ParseELFSections(std::vector<ModuleSectionDes> &des, std::vector<ElfSecName> &secs);
void ParseELFSections(BinaryBufferParser &parser, std::vector<ModuleSectionDes> &des, std::vector<ElfSecName> &secs);
bool ParseELFSegment();
ModuleSectionDes::ModuleRegionInfo GetCurModuleInfo(uint32_t i, llvm::ELF::Elf64_Off offset);
void SeparateTextSections(std::vector<ModuleSectionDes> &des, const uintptr_t &secAddr,
llvm::ELF::Elf64_Off &secOffset, const llvm::ELF::Elf64_Off &moduleInfoOffset);
void SeparateArkStackMapSections(std::vector<ModuleSectionDes> &des, const uintptr_t &secAddr,
llvm::ELF::Elf64_Off &secOffset, const llvm::ELF::Elf64_Off &moduleInfoOffset);
void SeparateTextSections(BinaryBufferParser &parser, std::vector<ModuleSectionDes> &des,
const uint64_t &secAddr, llvm::ELF::Elf64_Off &secOffset, const llvm::ELF::Elf64_Off &curShOffset);
void SeparateArkStackMapSections(BinaryBufferParser &parser, std::vector<ModuleSectionDes> &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<ModuleSectionDes::ModuleRegionInfo> moduleInfo_;
};
} // namespace panda::ecmascript
#endif // ECMASCRIPT_COMPILER_AOT_FILE_ELF_READER_H

View File

@ -18,113 +18,6 @@
#include <iomanip>
namespace panda::ecmascript {
void ModuleSectionDes::SaveSectionsInfo(std::ofstream &file)
{
uint32_t secInfoSize = GetSecInfosSize();
uint32_t secSize = 0;
file.write(reinterpret_cast<char *>(&secInfoSize), sizeof(secInfoSize));
std::multimap<std::string, double> SecMap;
for (auto &s : sectionsInfo_) {
uint8_t secName = static_cast<uint8_t>(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<double>(curSecSize)));
file.write(reinterpret_cast<char *>(&secName), sizeof(secName));
file.write(reinterpret_cast<char *>(&curSecSize), sizeof(curSecSize));
file.write(reinterpret_cast<char *>(curSecAddr), curSecSize);
}
std::shared_ptr<uint8_t> ptr = GetArkStackMapSharePtr();
uint32_t size = GetArkStackMapSize();
file.write(reinterpret_cast<char *>(&size), sizeof(size));
file.write(reinterpret_cast<char *>(ptr.get()), size);
uint32_t index = GetStartIndex();
uint32_t cnt = GetFuncCount();
file.write(reinterpret_cast<char *>(&index), sizeof(index));
file.write(reinterpret_cast<char *>(&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<void *>(secBegin), size);
SetArkStackMapSize(size);
SetArkStackMapPtr(reinterpret_cast<uint8_t *>(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<uintptr_t>(curUnitOffset);
for (uint8_t i = 0; i < secInfoSize; i++) {
uint8_t secName = 0;
parser.ParseBuffer(&secName, sizeof(secName));
auto secEnumName = static_cast<ElfSecName>(secName);
uint32_t secSize = 0;
parser.ParseBuffer(&secSize, sizeof(secSize));
SetSecSize(secSize, secEnumName);
parser.ParseBuffer(reinterpret_cast<void *>(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<char *>(&size), sizeof(size));
file.read(reinterpret_cast<char *>(secBegin), size);
SetArkStackMapSize(size);
SetArkStackMapPtr(reinterpret_cast<uint8_t *>(secBegin));
curUnitOffset += size;
uint32_t index = 0;
uint32_t cnt = 0;
file.read(reinterpret_cast<char *>(&index), sizeof(index));
file.read(reinterpret_cast<char *>(&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<char *>(&secInfoSize), sizeof(secInfoSize));
auto secBegin = codeAddress + static_cast<uintptr_t>(curUnitOffset);
for (uint8_t i = 0; i < secInfoSize; i++) {
uint8_t secName = 0;
file.read(reinterpret_cast<char *>(&secName), sizeof(secName));
auto secEnumName = static_cast<ElfSecName>(secName);
uint32_t secSize;
file.read(reinterpret_cast<char *>(&secSize), sizeof(secSize));
SetSecSize(secSize, secEnumName);
file.read(reinterpret_cast<char *>(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();

View File

@ -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<uint8_t> 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;

View File

@ -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<uint64_t>(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<uint32_t> moduleInfo = {1};
uint64_t secSizeInfoAddr = reinterpret_cast<uint64_t>(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<char *>(&header), sizeof(llvm::ELF::Elf64_Ehdr));
builder.PackStubELFSections(file);
builder.PackELFSegment(file);
file.close();
}
std::ofstream file(realPath.c_str(), std::ofstream::binary);
SetStubNum(entries_.size());
file.write(reinterpret_cast<char *>(&entryNum_), sizeof(entryNum_));
file.write(reinterpret_cast<char *>(entries_.data()), sizeof(FuncEntryDes) * entryNum_);
uint32_t moduleNum = GetCodeUnitsNum();
file.write(reinterpret_cast<char *>(&moduleNum), sizeof(moduleNum_));
file.write(reinterpret_cast<char *>(&totalCodeSize_), sizeof(totalCodeSize_));
uint32_t asmStubSize = GetAsmStubSize();
file.write(reinterpret_cast<char *>(&asmStubSize), sizeof(asmStubSize));
uint64_t asmStubAddr = GetAsmStubAddr();
file.write(reinterpret_cast<char *>(asmStubAddr), asmStubSize);
for (size_t i = 0; i < moduleNum; i++) {
des_[i].SaveSectionsInfo(file);
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;
}
file.close();
fileMapMem_ = FileMap(realPath.c_str(), FILE_RDONLY, PAGE_PROT_READ);
if (fileMapMem_.GetOriginAddr() == nullptr) {
LOG_ECMA(ERROR) << "File mmap failed";
return false;
}
PagePreRead(fileMapMem_.GetOriginAddr(), fileMapMem_.GetSize());
moduleNum_ = ASMSTUB_MODULE_NUM;
des_.resize(moduleNum_);
ElfReader reader(fileMapMem_);
std::vector<ElfSecName> 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<FuncEntryDes *>(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<uint8_t *>(_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<uint64_t>(stubsMem_.addr_);
uint32_t curUnitOffset = 0;
uint32_t asmStubSize = 0;
binBufparser.ParseBuffer(&asmStubSize, sizeof(asmStubSize));
ElfReader reader(stubsMem_);
std::vector<ElfSecName> 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<FuncEntryDes *>(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<void *>(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<ElfSecName> &StubFileInfo::GetDumpSectionNames()
{
static const std::vector<ElfSecName> 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();

View File

@ -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<ElfSecName> &GetDumpSectionNames();
void *asmStubAddr_ {nullptr};
size_t asmStubSize_ {0};
std::vector<int> asmStubTempHolder_ {};

View File

@ -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
};
@ -94,6 +96,10 @@ public:
value_ = ElfSecName::ARK_STACKMAP;
} 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()) {

View File

@ -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<uint64_t>(secInfo.first), sec);
moduleDes.SetSecSize(secInfo.second, sec);
moduleDes.SetSecAddrAndSize(sec, reinterpret_cast<uint64_t>(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)