mirror of
https://gitee.com/openharmony/arkcompiler_ets_runtime
synced 2024-10-07 08:03:29 +00:00
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:
parent
f9a8b44397
commit
4a7cd90fa0
15
BUILD.gn
15
BUILD.gn
@ -892,6 +892,14 @@ if (is_mingw) {
|
||||
}
|
||||
|
||||
ohos_source_set("libark_jsruntime_set") {
|
||||
if (is_ohos && is_standard_system) {
|
||||
stub_an_file_path = "/system/lib64/module/stub.an"
|
||||
} else {
|
||||
stub_an_file_path =
|
||||
rebase_path("$root_gen_dir/arkcompiler/ets_runtime/stub.an")
|
||||
}
|
||||
defines = [ "STUB_AN_FILE=\"${stub_an_file_path}\"" ]
|
||||
|
||||
sources = ecma_source
|
||||
sources += ecma_profiler_source
|
||||
sources += ecma_debugger_source
|
||||
@ -950,6 +958,13 @@ ohos_source_set("libark_jsruntime_test_set") {
|
||||
sources += ecma_platform_source
|
||||
|
||||
defines = [ "OHOS_UNIT_TEST" ]
|
||||
if (is_ohos && is_standard_system) {
|
||||
stub_an_file_path = "/system/lib64/module/stub.an"
|
||||
} else {
|
||||
stub_an_file_path =
|
||||
rebase_path("$root_gen_dir/arkcompiler/ets_runtime/stub.an")
|
||||
}
|
||||
defines += [ "STUB_AN_FILE=\"${stub_an_file_path}\"" ]
|
||||
deps = [
|
||||
"$ark_root/libpandafile:arkfile_header_deps",
|
||||
"$ark_third_party_root/icu/icu4c:shared_icui18n",
|
||||
|
@ -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;
|
||||
}
|
||||
@ -120,9 +114,9 @@ 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};
|
||||
static const std::vector<ElfSecName> secNames = {ElfSecName::RODATA_CST8, ElfSecName::TEXT,
|
||||
ElfSecName::STRTAB, ElfSecName::ARK_STACKMAP,
|
||||
ElfSecName::ARK_FUNCENTRY};
|
||||
return secNames;
|
||||
}
|
||||
|
||||
|
@ -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_) {
|
||||
|
@ -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};
|
||||
|
@ -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>> §ions = sectionDes_.GetSectionsInfo();
|
||||
// modify strtab
|
||||
for (auto &s : sections) {
|
||||
if (s.first == ElfSecName::STRTAB) {
|
||||
existedStrTab = true;
|
||||
strTabAddr = s.second.first;
|
||||
strTabSize = s.second.second;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for (auto &s : sections) {
|
||||
ElfSection section = ElfSection(s.first);
|
||||
if (!section.ShouldDumpToAOTFile()) {
|
||||
continue;
|
||||
}
|
||||
auto str = sectionDes_.GetSecName(s.first);
|
||||
llvm::ELF::Elf64_Word id = FindShName(str, strTabAddr, strTabSize);
|
||||
if (id == static_cast<llvm::ELF::Elf64_Word>(-1)) {
|
||||
sectionNames.emplace_back(str);
|
||||
}
|
||||
}
|
||||
uint32_t size = 0;
|
||||
if (existedStrTab) {
|
||||
size += strTabSize;
|
||||
}
|
||||
for (auto &str: sectionNames) {
|
||||
std::map<ElfSecName, std::pair<uint64_t, uint32_t>> §ions = des_[0].GetSectionsInfo();
|
||||
|
||||
uint32_t size = 1;
|
||||
for (auto &s : sections_) {
|
||||
std::string str = ModuleSectionDes::GetSecName(s);
|
||||
size = size + str.size() + 1;
|
||||
}
|
||||
|
||||
strTabPtr_ = std::make_unique<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>> §ions = sectionDes_.GetSectionsInfo();
|
||||
const std::map<ElfSecName, std::pair<uint64_t, uint32_t>> §ions = GetCurrentSecInfo();
|
||||
// dump
|
||||
for (auto &s : sections) {
|
||||
ElfSection section = ElfSection(s.first);
|
||||
@ -101,31 +70,35 @@ void ElfBuilder::DumpSection() const
|
||||
|
||||
void ElfBuilder::AddArkStackMapSection()
|
||||
{
|
||||
// add arkstackmap
|
||||
std::map<ElfSecName, std::pair<uint64_t, uint32_t>> §ions = sectionDes_.GetSectionsInfo();
|
||||
std::shared_ptr<uint8_t> ptr = sectionDes_.GetArkStackMapSharePtr();
|
||||
uint64_t arkStackMapAddr = reinterpret_cast<uint64_t>(ptr.get());
|
||||
uint32_t arkStackMapSize = sectionDes_.GetArkStackMapSize();
|
||||
if (arkStackMapSize > 0) {
|
||||
sections[ElfSecName::ARK_STACKMAP] = std::pair(arkStackMapAddr, arkStackMapSize);
|
||||
for (auto &des : des_) {
|
||||
std::map<ElfSecName, std::pair<uint64_t, uint32_t>> §ions = des.GetSectionsInfo();
|
||||
std::shared_ptr<uint8_t> ptr = des.GetArkStackMapSharePtr();
|
||||
uint64_t arkStackMapAddr = reinterpret_cast<uint64_t>(ptr.get());
|
||||
uint32_t arkStackMapSize = des.GetArkStackMapSize();
|
||||
if (arkStackMapSize > 0) {
|
||||
sections[ElfSecName::ARK_STACKMAP] = std::pair(arkStackMapAddr, arkStackMapSize);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ElfBuilder::ElfBuilder(ModuleSectionDes sectionDes): sectionDes_(sectionDes)
|
||||
ElfBuilder::ElfBuilder(const std::vector<ModuleSectionDes> &des,
|
||||
const std::vector<ElfSecName> §ions): des_(des), sections_(sections)
|
||||
{
|
||||
ASSERT(des_.size() == AOT_MODULE_NUM || des_.size() == ASMSTUB_MODULE_NUM);
|
||||
AddArkStackMapSection();
|
||||
ModifyStrTabSection();
|
||||
sectionToAlign_ = {
|
||||
{ElfSecName::RODATA, 8},
|
||||
{ElfSecName::RODATA_CST4, 8},
|
||||
{ElfSecName::RODATA_CST8, 8},
|
||||
{ElfSecName::RODATA_CST16, 8},
|
||||
{ElfSecName::RODATA_CST32, 8},
|
||||
{ElfSecName::TEXT, 16},
|
||||
{ElfSecName::RODATA, TEXT_SEC_ALIGN},
|
||||
{ElfSecName::RODATA_CST4, TEXT_SEC_ALIGN},
|
||||
{ElfSecName::RODATA_CST8, TEXT_SEC_ALIGN},
|
||||
{ElfSecName::RODATA_CST16, TEXT_SEC_ALIGN},
|
||||
{ElfSecName::RODATA_CST32, TEXT_SEC_ALIGN},
|
||||
{ElfSecName::TEXT, TEXT_SEC_ALIGN},
|
||||
{ElfSecName::STRTAB, 1},
|
||||
{ElfSecName::SYMTAB, 8},
|
||||
{ElfSecName::ARK_STACKMAP, 8},
|
||||
{ElfSecName::ARK_FUNCENTRY, 8},
|
||||
{ElfSecName::ARK_STACKMAP, DATA_SEC_ALIGN},
|
||||
{ElfSecName::ARK_FUNCENTRY, DATA_SEC_ALIGN},
|
||||
{ElfSecName::ARK_ASMSTUB, DATA_SEC_ALIGN},
|
||||
{ElfSecName::ARK_MODULEINFO, DATA_SEC_ALIGN},
|
||||
};
|
||||
|
||||
sectionToSegment_ = {
|
||||
@ -136,15 +109,31 @@ ElfBuilder::ElfBuilder(ModuleSectionDes sectionDes): sectionDes_(sectionDes)
|
||||
{ElfSecName::RODATA_CST32, ElfSecName::TEXT},
|
||||
{ElfSecName::TEXT, ElfSecName::TEXT},
|
||||
{ElfSecName::STRTAB, ElfSecName::DATA},
|
||||
{ElfSecName::SYMTAB, ElfSecName::DATA},
|
||||
{ElfSecName::ARK_STACKMAP, ElfSecName::DATA},
|
||||
{ElfSecName::ARK_FUNCENTRY, ElfSecName::DATA},
|
||||
{ElfSecName::ARK_ASMSTUB, ElfSecName::TEXT},
|
||||
{ElfSecName::ARK_MODULEINFO, ElfSecName::DATA},
|
||||
};
|
||||
|
||||
segmentToFlag_ = {
|
||||
{ElfSecName::TEXT, llvm::ELF::PF_X | llvm::ELF::PF_R},
|
||||
{ElfSecName::DATA, llvm::ELF::PF_R},
|
||||
};
|
||||
|
||||
RemoveNotNeedSection();
|
||||
}
|
||||
|
||||
void ElfBuilder::RemoveNotNeedSection()
|
||||
{
|
||||
const std::map<ElfSecName, std::pair<uint64_t, uint32_t>> §ions = GetCurrentSecInfo();
|
||||
for (size_t i = 0; i < sections_.size();) {
|
||||
if (sections.find(sections_[i]) == sections.end()) {
|
||||
auto it = sections_.begin() + i;
|
||||
sections_.erase(it);
|
||||
continue;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
ElfBuilder::~ElfBuilder()
|
||||
@ -152,49 +141,22 @@ ElfBuilder::~ElfBuilder()
|
||||
strTabPtr_ = nullptr;
|
||||
}
|
||||
|
||||
llvm::ELF::Elf64_Half ElfBuilder::GetShStrNdx(std::map<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;
|
||||
}
|
||||
shstrndx++;
|
||||
idx++;
|
||||
}
|
||||
UNREACHABLE();
|
||||
}
|
||||
|
||||
llvm::ELF::Elf64_Half ElfBuilder::GetSecSize() const
|
||||
{
|
||||
llvm::ELF::Elf64_Half secsSize = 0;
|
||||
const std::map<ElfSecName, std::pair<uint64_t, uint32_t>> §ions = sectionDes_.GetSectionsInfo();
|
||||
for (auto &s : sections) {
|
||||
ElfSection section = ElfSection(s.first);
|
||||
if (!section.ShouldDumpToAOTFile()) {
|
||||
continue;
|
||||
}
|
||||
uint32_t curSecSize = sectionDes_.GetSecSize(s.first);
|
||||
secsSize += curSecSize;
|
||||
}
|
||||
return secsSize;
|
||||
return -1;
|
||||
}
|
||||
|
||||
int ElfBuilder::GetSecNum() const
|
||||
{
|
||||
int secNum = 0;
|
||||
const std::map<ElfSecName, std::pair<uint64_t, uint32_t>> §ions = sectionDes_.GetSectionsInfo();
|
||||
for (auto &s : sections) {
|
||||
ElfSection section = ElfSection(s.first);
|
||||
if (!section.ShouldDumpToAOTFile()) {
|
||||
continue;
|
||||
}
|
||||
++secNum;
|
||||
}
|
||||
return secNum;
|
||||
return sections_.size();
|
||||
}
|
||||
|
||||
/*
|
||||
@ -203,14 +165,14 @@ ELF Header:
|
||||
Magic: 7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00
|
||||
Class: ELF64
|
||||
Data: 2's complement, little endian
|
||||
Version: 1
|
||||
Version: 1 (current)
|
||||
OS/ABI: UNIX - System V
|
||||
ABI Version: 0
|
||||
Type: DYN (Shared object file)
|
||||
Machine: Advanced Micro Devices X86-64
|
||||
Version: 0x2
|
||||
Version: 0x4000001
|
||||
Entry point address: 0x0
|
||||
Start of program headers: 20480 (bytes into file)
|
||||
Start of program headers: 16384 (bytes into file)
|
||||
Start of section headers: 64 (bytes into file)
|
||||
Flags: 0x0
|
||||
Size of this header: 64 (bytes)
|
||||
@ -219,7 +181,6 @@ ELF Header:
|
||||
Size of section headers: 64 (bytes)
|
||||
Number of section headers: 7
|
||||
Section header string table index: 3
|
||||
There are 7 section headers, starting at offset 0x40:
|
||||
*/
|
||||
void ElfBuilder::PackELFHeader(llvm::ELF::Elf64_Ehdr &header, uint32_t version, Triple triple)
|
||||
{
|
||||
@ -250,7 +211,6 @@ void ElfBuilder::PackELFHeader(llvm::ELF::Elf64_Ehdr &header, uint32_t version,
|
||||
break;
|
||||
}
|
||||
header.e_version = version;
|
||||
std::map<ElfSecName, std::pair<uint64_t, uint32_t>> §ions = sectionDes_.GetSectionsInfo();
|
||||
// start of section headers
|
||||
header.e_shoff = sizeof(llvm::ELF::Elf64_Ehdr);
|
||||
// size of ehdr
|
||||
@ -260,7 +220,9 @@ void ElfBuilder::PackELFHeader(llvm::ELF::Elf64_Ehdr &header, uint32_t version,
|
||||
// number of section headers
|
||||
header.e_shnum = GetSecNum() + 1; // 1: skip null section and ark stackmap
|
||||
// section header string table index
|
||||
header.e_shstrndx = GetShStrNdx(sections);
|
||||
header.e_shstrndx = static_cast<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>> §ions = sectionDes_.GetSectionsInfo();
|
||||
const std::map<ElfSecName, std::pair<uint64_t, uint32_t>> §ions = 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>> §ions = sectionDes_.GetSectionsInfo();
|
||||
const std::map<ElfSecName, std::pair<uint64_t, uint32_t>> §ions = GetCurrentSecInfo();
|
||||
for (auto &s: sections) {
|
||||
ElfSection section = ElfSection(s.first);
|
||||
if (!section.ShouldDumpToAOTFile()) {
|
||||
@ -306,7 +268,7 @@ ElfSecName ElfBuilder::FindLastSection(ElfSecName segment) const
|
||||
llvm::ELF::Elf64_Word ElfBuilder::FindShName(std::string name, uintptr_t strTabPtr, int strTabSize)
|
||||
{
|
||||
llvm::ELF::Elf64_Word ans = -1;
|
||||
int len = static_cast<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>> §ions = sectionDes_.GetSectionsInfo();
|
||||
const std::map<ElfSecName, std::pair<uint64_t, uint32_t>> §ions = GetCurrentSecInfo();
|
||||
uint64_t strTabAddr = 0;
|
||||
uint32_t strTabSize = 0;
|
||||
for (auto &s: sections) {
|
||||
uint32_t curSecSize = sectionDes_.GetSecSize(s.first);
|
||||
uint64_t curSecAddr = sectionDes_.GetSecAddr(s.first);
|
||||
uint32_t curSecSize = des_[0].GetSecSize(s.first);
|
||||
uint64_t curSecAddr = des_[0].GetSecAddr(s.first);
|
||||
if (s.first == ElfSecName::STRTAB) {
|
||||
strTabSize = curSecSize;
|
||||
strTabAddr = curSecAddr;
|
||||
@ -337,78 +299,142 @@ std::pair<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>> §ions = 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>> §ions = 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);
|
||||
file.seekp(curSecOffset);
|
||||
}
|
||||
auto it = sectionToSegment_.find(s.first);
|
||||
ASSERT(it != sectionToSegment_.end());
|
||||
ElfSecName segName = it->second;
|
||||
curShdr.sh_addralign = sectionToAlign_[secName];
|
||||
curSecOffset = AlignUp(curSecOffset, curShdr.sh_addralign);
|
||||
file.seekp(curSecOffset);
|
||||
ElfSecName segName = GetSegmentName(secName);
|
||||
segments_.insert(segName);
|
||||
uint32_t curSecSize = sectionDes_.GetSecSize(s.first);
|
||||
uint64_t curSecAddr = sectionDes_.GetSecAddr(s.first);
|
||||
std::string secName = sectionDes_.GetSecName(s.first);
|
||||
// text section address needs 16 bytes alignment
|
||||
if ((ElfSecName::RODATA <= s.first && s.first <= ElfSecName::RODATA_CST8) || s.first == ElfSecName::TEXT) {
|
||||
curSecOffset = AlignUp(curSecOffset, TEXT_SEC_ALIGN);
|
||||
file.seekp(curSecOffset);
|
||||
}
|
||||
sectionToFileOffset_[s.first] = static_cast<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>> §ions = 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>> §ions = sectionDes_.GetSectionsInfo();
|
||||
const std::map<ElfSecName, std::pair<uint64_t, uint32_t>> §ions = GetCurrentSecInfo();
|
||||
llvm::ELF::Elf64_Off offset = e_phoff;
|
||||
for (auto &s: sections) {
|
||||
ElfSection section = ElfSection(s.first);
|
||||
|
@ -30,38 +30,58 @@ class ModuleSectionDes;
|
||||
|
||||
class ElfBuilder {
|
||||
public:
|
||||
ElfBuilder(ModuleSectionDes sectionDes);
|
||||
ElfBuilder(const std::vector<ModuleSectionDes> &des, const std::vector<ElfSecName> §ions);
|
||||
~ElfBuilder();
|
||||
void PackELFHeader(llvm::ELF::Elf64_Ehdr &header, uint32_t version, Triple triple);
|
||||
void PackELFSections(std::ofstream &elfFile);
|
||||
void PackAnELFSections(std::ofstream &elfFile);
|
||||
void PackStubELFSections(std::ofstream &elfFile);
|
||||
void PackELFSegment(std::ofstream &elfFile);
|
||||
void MergeTextSections(std::ofstream &elfFile,
|
||||
std::vector<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>> §ions) const;
|
||||
llvm::ELF::Elf64_Half GetSecSize() const;
|
||||
uint32_t GetShIndex(ElfSecName section) const;
|
||||
ElfSecName FindLastSection(ElfSecName segment) const;
|
||||
int GetSegmentNum() const;
|
||||
int GetSecNum() const;
|
||||
unsigned GetPFlag(ElfSecName segment) const;
|
||||
ElfSecName GetSegmentName(const ElfSecName &secName) const;
|
||||
std::pair<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};
|
||||
};
|
||||
|
@ -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
|
@ -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
|
@ -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();
|
||||
|
@ -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;
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
bool StubFileInfo::MmapLoad()
|
||||
{
|
||||
std::string filename = STUB_AN_FILE;
|
||||
std::string realPath;
|
||||
if (!RealPath(filename, realPath, false)) {
|
||||
LOG_COMPILER(ERROR) << "Can not load stub file from path [ " << filename << " ], "
|
||||
<< "please execute ark_stub_compiler with options --stub-file.";
|
||||
return false;
|
||||
}
|
||||
|
||||
std::ofstream file(realPath.c_str(), std::ofstream::binary);
|
||||
SetStubNum(entries_.size());
|
||||
file.write(reinterpret_cast<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);
|
||||
fileMapMem_ = FileMap(realPath.c_str(), FILE_RDONLY, PAGE_PROT_READ);
|
||||
if (fileMapMem_.GetOriginAddr() == nullptr) {
|
||||
LOG_ECMA(ERROR) << "File mmap failed";
|
||||
return false;
|
||||
}
|
||||
file.close();
|
||||
PagePreRead(fileMapMem_.GetOriginAddr(), fileMapMem_.GetSize());
|
||||
moduleNum_ = ASMSTUB_MODULE_NUM;
|
||||
des_.resize(moduleNum_);
|
||||
|
||||
ElfReader reader(fileMapMem_);
|
||||
std::vector<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();
|
||||
|
@ -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_ {};
|
||||
|
@ -30,6 +30,7 @@ enum class ElfSecName : uint8_t {
|
||||
RODATA_CST16,
|
||||
RODATA_CST32,
|
||||
TEXT,
|
||||
ARK_ASMSTUB,
|
||||
DATA,
|
||||
GOT,
|
||||
RELATEXT,
|
||||
@ -38,6 +39,7 @@ enum class ElfSecName : uint8_t {
|
||||
LLVM_STACKMAP,
|
||||
ARK_FUNCENTRY,
|
||||
ARK_STACKMAP,
|
||||
ARK_MODULEINFO,
|
||||
SIZE
|
||||
};
|
||||
|
||||
@ -88,12 +90,16 @@ public:
|
||||
value_ = ElfSecName::STRTAB;
|
||||
} else if (str.compare(".symtab") == 0) {
|
||||
value_ = ElfSecName::SYMTAB;
|
||||
} else if (str.compare(".llvm_stackmaps") == 0) {
|
||||
} else if (str.compare(".llvm_stackmaps") == 0) {
|
||||
value_ = ElfSecName::LLVM_STACKMAP;
|
||||
} else if (str.compare(".ark_stackmaps") == 0) {
|
||||
} else if (str.compare(".ark_stackmaps") == 0) {
|
||||
value_ = ElfSecName::ARK_STACKMAP;
|
||||
} else if (str.compare(".ark_funcentry") == 0) {
|
||||
} else if (str.compare(".ark_funcentry") == 0) {
|
||||
value_ = ElfSecName::ARK_FUNCENTRY;
|
||||
} else if (str.compare(".ark_asmstub") == 0) {
|
||||
value_ = ElfSecName::ARK_ASMSTUB;
|
||||
} else if (str.compare(".ark_moduleinfo") == 0) {
|
||||
value_ = ElfSecName::ARK_MODULEINFO;
|
||||
}
|
||||
InitShTypeAndFlag();
|
||||
}
|
||||
@ -108,11 +114,11 @@ public:
|
||||
case ElfSecName::RODATA_CST16:
|
||||
case ElfSecName::RODATA_CST32:
|
||||
case ElfSecName::TEXT:
|
||||
case ElfSecName::DATA:
|
||||
case ElfSecName::SYMTAB:
|
||||
case ElfSecName::STRTAB:
|
||||
case ElfSecName::ARK_FUNCENTRY:
|
||||
case ElfSecName::ARK_STACKMAP: {
|
||||
case ElfSecName::ARK_ASMSTUB:
|
||||
case ElfSecName::ARK_STACKMAP:
|
||||
case ElfSecName::ARK_MODULEINFO: {
|
||||
saveForAot = true;
|
||||
break;
|
||||
}
|
||||
@ -123,6 +129,26 @@ public:
|
||||
return saveForAot;
|
||||
}
|
||||
|
||||
bool ShouldDumpToStubFile() const
|
||||
{
|
||||
bool saveForStub = false;
|
||||
switch (value_) {
|
||||
case ElfSecName::TEXT:
|
||||
case ElfSecName::STRTAB:
|
||||
case ElfSecName::ARK_FUNCENTRY:
|
||||
case ElfSecName::ARK_ASMSTUB:
|
||||
case ElfSecName::ARK_STACKMAP:
|
||||
case ElfSecName::ARK_MODULEINFO: {
|
||||
saveForStub = true;
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return saveForStub;
|
||||
}
|
||||
|
||||
ElfSecName Value() const
|
||||
{
|
||||
return value_;
|
||||
@ -150,6 +176,7 @@ public:
|
||||
{ElfSecName::RODATA_CST16, {llvm::ELF::SHT_PROGBITS, llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_MERGE}},
|
||||
{ElfSecName::RODATA_CST32, {llvm::ELF::SHT_PROGBITS, llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_MERGE}},
|
||||
{ElfSecName::TEXT, {llvm::ELF::SHT_PROGBITS, llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_EXECINSTR}},
|
||||
{ElfSecName::ARK_ASMSTUB, {llvm::ELF::SHT_PROGBITS, llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_EXECINSTR}},
|
||||
{ElfSecName::DATA, {llvm::ELF::SHT_PROGBITS, llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_WRITE}},
|
||||
{ElfSecName::GOT, {llvm::ELF::SHT_PROGBITS, llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_WRITE}},
|
||||
{ElfSecName::RELATEXT, {llvm::ELF::SHT_RELA, llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_WRITE}},
|
||||
@ -158,6 +185,7 @@ public:
|
||||
{ElfSecName::LLVM_STACKMAP, {llvm::ELF::SHT_RELA, llvm::ELF::SHF_ALLOC}},
|
||||
{ElfSecName::ARK_FUNCENTRY, {llvm::ELF::SHF_WRITE, llvm::ELF::SHF_ALLOC}},
|
||||
{ElfSecName::ARK_STACKMAP, {llvm::ELF::SHF_WRITE, llvm::ELF::SHF_ALLOC}},
|
||||
{ElfSecName::ARK_MODULEINFO, {llvm::ELF::SHF_WRITE, llvm::ELF::SHF_ALLOC}},
|
||||
};
|
||||
auto it = nameToTypeAndFlag.find(value_);
|
||||
if (it == nameToTypeAndFlag.end()) {
|
||||
|
@ -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)
|
||||
|
Loading…
Reference in New Issue
Block a user