Deal with .rodata.cst16 when build an file

Issue:https://gitee.com/openharmony/arkcompiler_ets_runtime/issues/I7M6ST?from=project-issue
Signed-off-by: zhangyukun8 <zhangyukun8@huawei.com>

Change-Id: I7e1e913cedc545be491d50c43f953206c8662472
This commit is contained in:
zhangyukun8 2023-07-19 09:49:38 +08:00
parent 60cf2d56d6
commit 67f20ea93f
14 changed files with 133 additions and 38 deletions

View File

@ -46,6 +46,7 @@ static constexpr double MAX_VALUE = std::numeric_limits<double>::max();
static constexpr double MIN_VALUE = std::numeric_limits<double>::min();
static constexpr double POSITIVE_INFINITY = std::numeric_limits<double>::infinity();
static constexpr double NAN_VALUE = std::numeric_limits<double>::quiet_NaN();
static constexpr uint64_t MAX_UINT64_VALUE = std::numeric_limits<uint64_t>::max();
// Helper defines for double
static constexpr int DOUBLE_MAX_PRECISION = 17;

View File

@ -32,8 +32,9 @@ public:
AOTFileInfo() = default;
virtual ~AOTFileInfo() = default;
static constexpr uint32_t TEXT_SEC_ALIGN = 16;
static constexpr uint32_t DATA_SEC_ALIGN = 8;
static constexpr uint32_t TEXT_SEC_ALIGN = 4096;
static constexpr uint32_t PAGE_ALIGN = 4096;
struct FuncEntryDes {
uint64_t codeAddr_ {};

View File

@ -83,12 +83,7 @@ void ElfBuilder::Initialize()
des_[i].AddArkStackMapSection();
}
sectionToAlign_ = {
{ElfSecName::RODATA, AOTFileInfo::TEXT_SEC_ALIGN},
{ElfSecName::RODATA_CST4, AOTFileInfo::TEXT_SEC_ALIGN},
{ElfSecName::RODATA_CST8, AOTFileInfo::TEXT_SEC_ALIGN},
{ElfSecName::RODATA_CST16, AOTFileInfo::TEXT_SEC_ALIGN},
{ElfSecName::RODATA_CST32, AOTFileInfo::TEXT_SEC_ALIGN},
{ElfSecName::TEXT, AOTFileInfo::TEXT_SEC_ALIGN},
{ElfSecName::TEXT, AOTFileInfo::PAGE_ALIGN},
{ElfSecName::STRTAB, 1},
{ElfSecName::SYMTAB, AOTFileInfo::DATA_SEC_ALIGN},
{ElfSecName::SHSTRTAB, AOTFileInfo::DATA_SEC_ALIGN},
@ -331,20 +326,19 @@ void ElfBuilder::MergeTextSections(std::ofstream &file,
ModuleSectionDes::ModuleRegionInfo &curInfo = moduleInfo[i];
uint32_t curSecSize = des.GetSecSize(ElfSecName::TEXT);
uint64_t curSecAddr = des.GetSecAddr(ElfSecName::TEXT);
curSecOffset = AlignUp(curSecOffset, AOTFileInfo::TEXT_SEC_ALIGN);
curSecOffset = AlignUp(curSecOffset, AOTFileInfo::PAGE_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()) {
rodataSize = des.GetSecSize(ElfSecName::RODATA_CST8);
rodataAddr = des.GetSecAddr(ElfSecName::RODATA_CST8);
}
std::tie(rodataAddr, rodataSize) = des.GetMergedRODataAddrAndSize();
if (rodataSize != 0 && rodataAddr < curSecAddr) {
file.write(reinterpret_cast<char *>(rodataAddr), rodataSize);
curInfo.rodataSize = rodataSize;
curSecOffset += rodataSize;
curSecOffset = AlignUp(curSecOffset, AOTFileInfo::TEXT_SEC_ALIGN);
file.seekp(curSecOffset);
}
file.write(reinterpret_cast<char *>(curSecAddr), curSecSize);
curInfo.textSize = curSecSize;
@ -441,7 +435,7 @@ void ElfBuilder::PackELFSections(std::ofstream &file)
std::string secNameStr = ModuleSectionDes::GetSecName(secName);
// text section address needs 16 bytes alignment
if (secName == ElfSecName::TEXT) {
curSecOffset = AlignUp(curSecOffset, AOTFileInfo::TEXT_SEC_ALIGN);
curSecOffset = AlignUp(curSecOffset, AOTFileInfo::PAGE_ALIGN);
file.seekp(curSecOffset);
}
llvm::ELF::Elf64_Word shName = FindShName(secNameStr, shStrTab.first, shStrTab.second);

View File

@ -256,18 +256,19 @@ void ElfReader::SeparateTextSections(std::vector<ModuleSectionDes> &des,
{
for (size_t i = 0; i < des.size(); ++i) {
auto moduleInfo = GetCurModuleInfo(i, moduleInfoOffset);
secOffset = AlignUp(secOffset, TEXT_SEC_ALIGN);
secOffset = AlignUp(secOffset, AOTFileInfo::PAGE_ALIGN);
uint32_t rodataSize = moduleInfo->rodataSize;
uint32_t rodataAfterText = moduleInfo->rodataAfterText;
if (rodataSize > 0 && rodataAfterText == 0) {
des[i].SetSecAddrAndSize(ElfSecName::RODATA_CST8, secAddr + secOffset, rodataSize);
secOffset += rodataSize;
secOffset = AlignUp(secOffset, AOTFileInfo::TEXT_SEC_ALIGN);
}
uint32_t textSize = moduleInfo->textSize;
des[i].SetSecAddrAndSize(ElfSecName::TEXT, secAddr + secOffset, textSize);
secOffset += textSize;
if (rodataSize > 0 && rodataAfterText == 1) {
secOffset = AlignUp(secOffset, DATA_SEC_ALIGN);
secOffset = AlignUp(secOffset, AOTFileInfo::DATA_SEC_ALIGN);
des[i].SetSecAddrAndSize(ElfSecName::RODATA_CST8, secAddr + secOffset, rodataSize);
secOffset += rodataSize;
}
@ -300,20 +301,21 @@ void ElfReader::SeparateTextSections(BinaryBufferParser &parser,
{
for (size_t i = 0; i < des.size(); ++i) {
auto moduleInfo = moduleInfo_[i];
secOffset = AlignUp(secOffset, TEXT_SEC_ALIGN);
secOffset = AlignUp(secOffset, AOTFileInfo::PAGE_ALIGN);
uint32_t rodataSize = moduleInfo.rodataSize;
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;
secOffset = AlignUp(secOffset, AOTFileInfo::TEXT_SEC_ALIGN);
}
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;
if (rodataSize > 0 && rodataAfterText == 1) {
secOffset = AlignUp(secOffset, DATA_SEC_ALIGN);
secOffset = AlignUp(secOffset, AOTFileInfo::DATA_SEC_ALIGN);
parser.ParseBuffer(reinterpret_cast<void *>(secAddr + secOffset), rodataSize, curShOffset + secOffset);
des[i].SetSecAddrAndSize(ElfSecName::RODATA_CST8, secAddr + secOffset, rodataSize);
secOffset += rodataSize;

View File

@ -53,8 +53,6 @@ private:
return moduleInfoSize / sizeof(ModuleSectionDes::ModuleRegionInfo);
}
static constexpr uint32_t TEXT_SEC_ALIGN = 4096;
static constexpr uint32_t DATA_SEC_ALIGN = 8;
static constexpr uint32_t ASMSTUB_MODULE_NUM = 3;
ExecutedMemoryAllocator::ExeMem stubsMem_ {};
MemMap fileMapMem_ {};

View File

@ -18,6 +18,7 @@
#include <cstdint>
#include <memory>
#include "ecmascript/base/number_helper.h"
#include "ecmascript/compiler/aot_file/binary_buffer_parser.h"
#include "ecmascript/compiler/binary_section.h"
@ -34,6 +35,28 @@ public:
};
static std::string GetSecName(ElfSecName idx);
void UpdateRODataInfo(uint64_t &addr, uint32_t &size, ElfSecName sec) const
{
if (sectionsInfo_.find(sec) == sectionsInfo_.end()) {
return;
}
uint64_t curSectionAddr = GetSecAddr(sec);
addr = curSectionAddr < addr ? curSectionAddr : addr;
size += GetSecSize(sec);
}
std::tuple<uint64_t, uint32_t> GetMergedRODataAddrAndSize() const
{
uint64_t addr = base::MAX_UINT64_VALUE;
uint32_t size = 0;
UpdateRODataInfo(addr, size, ElfSecName::RODATA);
UpdateRODataInfo(addr, size, ElfSecName::RODATA_CST4);
UpdateRODataInfo(addr, size, ElfSecName::RODATA_CST8);
UpdateRODataInfo(addr, size, ElfSecName::RODATA_CST16);
UpdateRODataInfo(addr, size, ElfSecName::RODATA_CST32);
return std::make_tuple(addr, size);
}
void SetArkStackMapPtr(std::shared_ptr<uint8_t> ptr)
{
arkStackMapPtr_ = std::move(ptr);

View File

@ -212,7 +212,7 @@ public:
// RO data section needs 16 bytes alignment
bool InRodataSection() const
{
return ElfSecName::RODATA <= value_ && value_ <= ElfSecName::RODATA_CST8;
return ElfSecName::RODATA <= value_ && value_ <= ElfSecName::RODATA_CST32;
}
private:
static int const FIX_SIZE = 24; // 24:Elf_Rel

View File

@ -122,11 +122,13 @@ 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(AOTFileInfo::TEXT_SEC_ALIGN);
uintptr_t rodataAddr = 0;
uint32_t rodataSize = 0;
std::tie(rodataAddr, rodataSize) = GetMergedRODataAddrAndSize();
aotInfo.AlignTextSec(AOTFileInfo::PAGE_ALIGN);
if (rodataAddr < textAddr) {
aotInfo.UpdateCurTextSecOffset(rodataSize);
aotInfo.AlignTextSec(AOTFileInfo::TEXT_SEC_ALIGN);
}
const size_t funcCount = funcInfo.size();
@ -270,10 +272,11 @@ void StubFileGenerator::DisassembleAsmStubs(std::map<uintptr_t, std::string> &ad
uint64_t AOTFileGenerator::RollbackTextSize(Module *module)
{
uintptr_t textAddr = module->GetSectionAddr(ElfSecName::TEXT);
uintptr_t rodataAddr = module->GetSectionAddr(ElfSecName::RODATA_CST8);
uint64_t textAddr = module->GetSectionAddr(ElfSecName::TEXT);
uint32_t textSize = module->GetSectionSize(ElfSecName::TEXT);
uint32_t rodataSize = module->GetSectionSize(ElfSecName::RODATA_CST8);
uint64_t rodataAddr = 0;
uint32_t rodataSize = 0;
std::tie(rodataAddr, rodataSize) = module->GetMergedRODataAddrAndSize();
uint64_t textStart = 0;
if (textAddr > rodataAddr) {
textStart = aotInfo_.GetCurTextSecOffset() - textSize;

View File

@ -16,6 +16,7 @@
#ifndef ECMASCRIPT_COMPILER_FILE_GENERATORS_H
#define ECMASCRIPT_COMPILER_FILE_GENERATORS_H
#include "ecmascript/base/number_helper.h"
#include "ecmascript/compiler/aot_file/aot_file_manager.h"
#include "ecmascript/compiler/assembler_module.h"
#include "ecmascript/compiler/compiler_log.h"
@ -58,6 +59,18 @@ public:
uintptr_t GetSectionAddr(ElfSecName sec) const;
std::tuple<uint64_t, uint32_t> GetMergedRODataAddrAndSize() const
{
uint64_t addr = base::MAX_UINT64_VALUE;
uint32_t size = 0;
UpdateRODataInfo(addr, size, ElfSecName::RODATA);
UpdateRODataInfo(addr, size, ElfSecName::RODATA_CST4);
UpdateRODataInfo(addr, size, ElfSecName::RODATA_CST8);
UpdateRODataInfo(addr, size, ElfSecName::RODATA_CST16);
UpdateRODataInfo(addr, size, ElfSecName::RODATA_CST32);
return std::make_tuple(addr, size);
}
void RunAssembler(const CompilerLog &log, bool fastCompileMode);
void DisassemblerFunc(std::map<uintptr_t, std::string> &addr2name, uint64_t textOffset, const CompilerLog &log,
@ -81,14 +94,11 @@ private:
return assembler_->GetSectionSize(ElfSecName::TEXT);
}
uintptr_t GetRODataAddr() const
void UpdateRODataInfo(uint64_t &addr, uint32_t &size, ElfSecName sec) const
{
return assembler_->GetSectionAddr(ElfSecName::RODATA_CST8);
}
uint32_t GetRODataSize() const
{
return assembler_->GetSectionSize(ElfSecName::RODATA_CST8);
uint64_t curSectionAddr = GetSectionAddr(sec);
addr = ((curSectionAddr != 0) && (curSectionAddr < addr)) ? curSectionAddr : addr;
size += GetSectionSize(sec);
}
LLVMModule *llvmModule_ {nullptr};

View File

@ -149,9 +149,13 @@ uint8_t *CodeInfo::AllocaCodeSection(uintptr_t size, const char *sectionName)
{
uint8_t *addr = nullptr;
auto curSec = ElfSection(sectionName);
if (curSec.isValidAOTSec() && !alreadyPageAlign_) {
addr = AllocaInReqSecBuffer(size, AOTFileInfo::TEXT_SEC_ALIGN);
if (curSec.isValidAOTSec()) {
if (!alreadyPageAlign_) {
addr = AllocaInReqSecBuffer(size, AOTFileInfo::PAGE_ALIGN);
alreadyPageAlign_ = true;
} else {
addr = AllocaInReqSecBuffer(size, AOTFileInfo::TEXT_SEC_ALIGN);
}
} else {
addr = AllocaInReqSecBuffer(size);
}
@ -170,8 +174,8 @@ uint8_t *CodeInfo::AllocaDataSection(uintptr_t size, const char *sectionName)
if (curSec.InRodataSection()) {
size = AlignUp(size, static_cast<size_t>(MemAlignment::MEM_ALIGN_REGION));
if (!alreadyPageAlign_) {
addr = curSec.isSequentialAOTSec() ? AllocaInReqSecBuffer(size, AOTFileInfo::TEXT_SEC_ALIGN)
: AllocaInNotReqSecBuffer(size, AOTFileInfo::TEXT_SEC_ALIGN);
addr = curSec.isSequentialAOTSec() ? AllocaInReqSecBuffer(size, AOTFileInfo::PAGE_ALIGN)
: AllocaInNotReqSecBuffer(size, AOTFileInfo::PAGE_ALIGN);
alreadyPageAlign_ = true;
} else {
addr = curSec.isSequentialAOTSec() ? AllocaInReqSecBuffer(size, AOTFileInfo::DATA_SEC_ALIGN)

View File

@ -154,6 +154,7 @@ group("ark_aot_ts_test") {
"poplexenv",
"proxy",
"resumegenerator",
"rodata",
"setobjectwithproto",
"shl",
"shr",

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_test_action("rodata") {
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.5
1.5

View File

@ -0,0 +1,25 @@
/*
* 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.
*/
declare function print(arg: any): string;
function foo(x: number, p: Function) {
let f3: number = 1.5
p(f3)
if (x == 1) {
f3 += 1.1
}
return f3
}
print(foo(2, print))