Support Dynamic Adjust The Sequence of .rodata And .text

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

Signed-off-by: wu_zhang_da <wuzhangda@huawei.com>
Change-Id: I3ff14b3f975aa4a68ecb844777a4941551fc0507
This commit is contained in:
wu_zhang_da 2023-07-08 10:33:25 +08:00
parent b0ba8a74b0
commit 0760c03614
12 changed files with 125 additions and 22 deletions

View File

@ -25,7 +25,7 @@ public:
// Release Version Snapshot Version
// 3.2 0.0.0.x
// 4.0 4.0.0.x
static constexpr base::FileHeaderBase::VersionType AN_VERSION = {4, 0, 0, 3};
static constexpr base::FileHeaderBase::VersionType AN_VERSION = {4, 0, 0, 4};
static constexpr bool AN_STRICT_MATCH = true;
static constexpr base::FileHeaderBase::VersionType AI_VERSION = {4, 0, 0, 1};
static constexpr bool AI_STRICT_MATCH = true;

View File

@ -334,16 +334,28 @@ void ElfBuilder::MergeTextSections(std::ofstream &file,
curSecOffset = AlignUp(curSecOffset, AOTFileInfo::TEXT_SEC_ALIGN);
file.seekp(curSecOffset);
auto curModuleSec = des.GetSectionsInfo();
uint32_t rodataSize = 0;
uint64_t rodataAddr = 0;
curInfo.rodataAfterText = 0;
if (curModuleSec.find(ElfSecName::RODATA_CST8) != curModuleSec.end()) {
uint32_t rodataSize = des.GetSecSize(ElfSecName::RODATA_CST8);
uint64_t rodataAddr = des.GetSecAddr(ElfSecName::RODATA_CST8);
rodataSize = des.GetSecSize(ElfSecName::RODATA_CST8);
rodataAddr = des.GetSecAddr(ElfSecName::RODATA_CST8);
}
if (rodataSize != 0 && rodataAddr < curSecAddr) {
file.write(reinterpret_cast<char *>(rodataAddr), rodataSize);
curInfo.rodataSize = rodataSize;
curSecOffset += rodataSize;
}
curInfo.textSize = curSecSize;
file.write(reinterpret_cast<char *>(curSecAddr), curSecSize);
curInfo.textSize = curSecSize;
curSecOffset += curSecSize;
if (rodataSize != 0 && rodataAddr > curSecAddr) {
file.write(reinterpret_cast<char *>(rodataAddr), rodataSize);
curInfo.rodataSize = rodataSize;
curSecOffset += rodataSize;
// .rodata is written after .text
curInfo.rodataAfterText = 1;
}
}
}

View File

@ -258,13 +258,18 @@ void ElfReader::SeparateTextSections(std::vector<ModuleSectionDes> &des,
auto moduleInfo = GetCurModuleInfo(i, moduleInfoOffset);
secOffset = AlignUp(secOffset, TEXT_SEC_ALIGN);
uint32_t rodataSize = moduleInfo->rodataSize;
if (rodataSize > 0) {
uint32_t rodataAfterText = moduleInfo->rodataAfterText;
if (rodataSize > 0 && rodataAfterText == 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;
if (rodataSize > 0 && rodataAfterText == 1) {
des[i].SetSecAddrAndSize(ElfSecName::RODATA_CST8, secAddr + secOffset, rodataSize);
secOffset += rodataSize;
}
}
}
@ -296,7 +301,8 @@ void ElfReader::SeparateTextSections(BinaryBufferParser &parser,
auto moduleInfo = moduleInfo_[i];
secOffset = AlignUp(secOffset, TEXT_SEC_ALIGN);
uint32_t rodataSize = moduleInfo.rodataSize;
if (rodataSize > 0) {
uint32_t rodataAfterText = moduleInfo.rodataAfterText;
if (rodataSize > 0 && rodataAfterText == 0) {
parser.ParseBuffer(reinterpret_cast<void *>(secAddr + secOffset), rodataSize, curShOffset + secOffset);
des[i].SetSecAddrAndSize(ElfSecName::RODATA_CST8, secAddr + secOffset, rodataSize);
secOffset += rodataSize;
@ -305,6 +311,11 @@ void ElfReader::SeparateTextSections(BinaryBufferParser &parser,
parser.ParseBuffer(reinterpret_cast<void *>(secAddr + secOffset), textSize, curShOffset + secOffset);
des[i].SetSecAddrAndSize(ElfSecName::TEXT, secAddr + secOffset, textSize);
secOffset += textSize;
if (rodataSize > 0 && rodataAfterText == 1) {
parser.ParseBuffer(reinterpret_cast<void *>(secAddr + secOffset), rodataSize, curShOffset + secOffset);
des[i].SetSecAddrAndSize(ElfSecName::RODATA_CST8, secAddr + secOffset, rodataSize);
secOffset += rodataSize;
}
}
}

View File

@ -30,6 +30,7 @@ public:
uint32_t rodataSize {0};
uint32_t textSize {0};
uint32_t stackMapSize {0};
uint32_t rodataAfterText {0};
};
static std::string GetSecName(ElfSecName idx);

View File

@ -122,9 +122,12 @@ void Module::CollectFuncEntryInfo(std::map<uintptr_t, std::string> &addr2name, A
// 2.After all functions compiled, the module sections would be fixed
uintptr_t textAddr = GetTextAddr();
uint32_t textSize = GetTextSize();
uintptr_t rodataAddr = GetRODataAddr();
uint32_t rodataSize = GetRODataSize();
aotInfo.AlignTextSec();
aotInfo.UpdateCurTextSecOffset(rodataSize);
if (rodataAddr < textAddr) {
aotInfo.UpdateCurTextSecOffset(rodataSize);
}
const size_t funcCount = funcInfo.size();
funcCount_ = funcCount;
@ -149,6 +152,9 @@ void Module::CollectFuncEntryInfo(std::map<uintptr_t, std::string> &addr2name, A
offset, moduleIndex, delta, funcSize, calleeSaveRegisters[i]);
}
aotInfo.UpdateCurTextSecOffset(textSize);
if (rodataAddr > textAddr) {
aotInfo.UpdateCurTextSecOffset(rodataSize);
}
}
void Module::CollectModuleSectionDes(ModuleSectionDes &moduleDes) const
@ -263,7 +269,12 @@ void StubFileGenerator::DisassembleAsmStubs(std::map<uintptr_t, std::string> &ad
uint64_t AOTFileGenerator::RollbackTextSize(Module *module)
{
return aotInfo_.GetCurTextSecOffset() - module->GetSectionSize(ElfSecName::TEXT);
uintptr_t textAddr = module->GetSectionAddr(ElfSecName::TEXT);
uintptr_t rodataAddr = module->GetSectionAddr(ElfSecName::RODATA_CST8);
uint32_t textSize = module->GetSectionSize(ElfSecName::TEXT);
uint32_t rodataSize = module->GetSectionSize(ElfSecName::RODATA_CST8);
return textAddr > rodataAddr ? (aotInfo_.GetCurTextSecOffset() - textSize) :
(aotInfo_.GetCurTextSecOffset() - textSize - rodataSize);
}
void AOTFileGenerator::CollectCodeInfo(Module *module, uint32_t moduleIdx)

View File

@ -81,6 +81,11 @@ private:
return assembler_->GetSectionSize(ElfSecName::TEXT);
}
uintptr_t GetRODataAddr() const
{
return assembler_->GetSectionAddr(ElfSecName::RODATA_CST8);
}
uint32_t GetRODataSize() const
{
return assembler_->GetSectionSize(ElfSecName::RODATA_CST8);

View File

@ -112,12 +112,8 @@ CodeInfo::CodeSpace::~CodeSpace()
unreqSecs_ = nullptr;
}
uint8_t *CodeInfo::CodeSpace::Alloca(uintptr_t size, bool isReq, size_t alignSize, bool alignFlag)
uint8_t *CodeInfo::CodeSpace::Alloca(uintptr_t size, bool isReq, size_t alignSize)
{
// align up for rodata section
if (alignFlag) {
size = AlignUp(size, static_cast<size_t>(MemAlignment::MEM_ALIGN_REGION));
}
uint8_t *addr = nullptr;
auto bufBegin = isReq ? reqSecs_ : unreqSecs_;
auto &curPos = isReq ? reqBufPos_ : unreqBufPos_;
@ -135,9 +131,9 @@ uint8_t *CodeInfo::CodeSpace::Alloca(uintptr_t size, bool isReq, size_t alignSiz
return addr;
}
uint8_t *CodeInfo::AllocaInReqSecBuffer(uintptr_t size, size_t alignSize, bool alignFlag)
uint8_t *CodeInfo::AllocaInReqSecBuffer(uintptr_t size, size_t alignSize)
{
return CodeSpace::GetInstance()->Alloca(size, true, alignSize, alignFlag);
return CodeSpace::GetInstance()->Alloca(size, true, alignSize);
}
uint8_t *CodeInfo::AllocaInNotReqSecBuffer(uintptr_t size, size_t alignSize)
@ -147,9 +143,14 @@ uint8_t *CodeInfo::AllocaInNotReqSecBuffer(uintptr_t size, size_t alignSize)
uint8_t *CodeInfo::AllocaCodeSection(uintptr_t size, const char *sectionName)
{
// if have got section, don't use align.
uint8_t *addr = AllocaInReqSecBuffer(size, false);
uint8_t *addr = nullptr;
auto curSec = ElfSection(sectionName);
if (curSec.isValidAOTSec() && !alreadyPageAlign_) {
addr = AllocaInReqSecBuffer(size, AOTFileInfo::TEXT_SEC_ALIGN);
alreadyPageAlign_ = true;
} else {
addr = AllocaInReqSecBuffer(size);
}
codeInfo_.push_back({addr, size});
if (curSec.isValidAOTSec()) {
secInfos_[curSec.GetIntIndex()] = std::make_pair(addr, size);
@ -164,8 +165,13 @@ uint8_t *CodeInfo::AllocaDataSection(uintptr_t size, const char *sectionName)
// rodata section needs 16 bytes alignment
if (curSec.InRodataSection()) {
size = AlignUp(size, static_cast<size_t>(MemAlignment::MEM_ALIGN_REGION));
addr = curSec.isSequentialAOTSec() ? AllocaInReqSecBuffer(size, AOTFileInfo::TEXT_SEC_ALIGN)
: AllocaInNotReqSecBuffer(size, AOTFileInfo::TEXT_SEC_ALIGN);
if (!alreadyPageAlign_) {
addr = curSec.isSequentialAOTSec() ? AllocaInReqSecBuffer(size, AOTFileInfo::TEXT_SEC_ALIGN)
: AllocaInNotReqSecBuffer(size, AOTFileInfo::TEXT_SEC_ALIGN);
alreadyPageAlign_ = true;
} else {
addr = curSec.isSequentialAOTSec() ? AllocaInReqSecBuffer(size) : AllocaInNotReqSecBuffer(size);
}
} else {
addr = curSec.isSequentialAOTSec() ? AllocaInReqSecBuffer(size) : AllocaInNotReqSecBuffer(size);
}

View File

@ -56,7 +56,7 @@ struct CodeInfo {
public:
static CodeSpace *GetInstance();
uint8_t *Alloca(uintptr_t size, bool isReq, size_t alignSize, bool alignFlag = true);
uint8_t *Alloca(uintptr_t size, bool isReq, size_t alignSize);
private:
CodeSpace();
@ -73,7 +73,7 @@ struct CodeInfo {
size_t unreqBufPos_ {0};
};
uint8_t *AllocaInReqSecBuffer(uintptr_t size, size_t alignSize = 0, bool alignFlag = true);
uint8_t *AllocaInReqSecBuffer(uintptr_t size, size_t alignSize = 0);
uint8_t *AllocaInNotReqSecBuffer(uintptr_t size, size_t alignSize = 0);
@ -103,6 +103,7 @@ struct CodeInfo {
private:
std::array<sectionInfo, static_cast<int>(ElfSecName::SIZE)> secInfos_;
std::vector<std::pair<uint8_t *, uintptr_t>> codeInfo_ {}; // info for disasssembler, planed to be deprecated
bool alreadyPageAlign_ {false};
};
enum class FPFlag : uint32_t {

View File

@ -18,7 +18,7 @@ group("ark_aot_js_test") {
"bigint_typed_array_constructors",
"call_default_args",
"constructor_returns_non_object",
"tryldglobalbyname",
"dynamicimport",
"emptyif",
"formatrangetoparts",

View File

@ -0,0 +1,18 @@
# Copyright (c) 2023 Huawei Device Co., Ltd.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import("//arkcompiler/ets_runtime/test/test_helper.gni")
host_aot_js_test_action("tryldglobalbyname") {
deps = []
}

View File

@ -0,0 +1,15 @@
# Copyright (c) 2023 Huawei Device Co., Ltd.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
-1.1
1.1

View File

@ -0,0 +1,23 @@
/*
* Copyright (c) 2023 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
function getPatternParts(positive) {
var n = positive ? 1.1 : -1.1;
return n;
}
let a = getPatternParts(false)
print(a)
let b = getPatternParts(true)
print(b)