Revert "Implement __llvm_deoptimize to void relocate deopt hander"

This reverts commit 9a05e60cfc.

issue: https://gitee.com/openharmony/arkcompiler_ets_runtime/issues/I6I8LN?from=project-issue
Change-Id: I44d512f9b29229b29860eea87f3a0f9e7ed54c34
Signed-off-by: songzhengchao <songzhengchao@huawei.com>
This commit is contained in:
songzhengchao 2023-02-28 09:25:30 +08:00
parent 5f56827f75
commit dac99d6453
9 changed files with 324 additions and 113 deletions

View File

@ -521,6 +521,7 @@ ecma_source = [
"ecmascript/date_parse.cpp",
"ecmascript/deoptimizer/calleeReg.cpp",
"ecmascript/deoptimizer/deoptimizer.cpp",
"ecmascript/deoptimizer/relocator.cpp",
"ecmascript/dfx/stackinfo/js_stackinfo.cpp",
"ecmascript/dfx/vmstat/caller_stat.cpp",
"ecmascript/dfx/vmstat/opt_code_profiler.cpp",

View File

@ -19,6 +19,7 @@
#include "ecmascript/compiler/common_stubs.h"
#include "ecmascript/compiler/compiler_log.h"
#include "ecmascript/deoptimizer/deoptimizer.h"
#include "ecmascript/deoptimizer/relocator.h"
#include "ecmascript/ecma_vm.h"
#include "ecmascript/message_string.h"
#include "ecmascript/jspandafile/constpool_value.h"
@ -257,6 +258,41 @@ void AnFileInfo::Save(const std::string &filename, kungfu::Triple triple)
file.close();
}
void AnFileInfo::RewriteRelcateDeoptHandler([[maybe_unused]] EcmaVM *vm)
{
#if !WIN_OR_MAC_OR_IOS_PLATFORM
JSThread *thread = vm->GetJSThread();
uintptr_t patchAddr = thread->GetRTInterface(RTSTUB_ID(DeoptHandlerAsm));
RewriteRelcateTextSection(LLVM_DEOPT_RELOCATE_SYMBOL, patchAddr);
#endif
}
void AnFileInfo::RewriteRelcateTextSection([[maybe_unused]] const char* symbol,
[[maybe_unused]] uintptr_t patchAddr)
{
#if !WIN_OR_MAC_OR_IOS_PLATFORM
for (auto &des: des_) {
uint32_t relaTextSize = des.GetSecSize(ElfSecName::RELATEXT);
if (relaTextSize != 0) {
uint64_t relatextAddr = des.GetSecAddr(ElfSecName::RELATEXT);
uint64_t textAddr = des.GetSecAddr(ElfSecName::TEXT);
uint64_t symTabAddr = des.GetSecAddr(ElfSecName::SYMTAB);
uint32_t symTabSize = des.GetSecSize(ElfSecName::SYMTAB);
uint32_t strTabSize = des.GetSecSize(ElfSecName::STRTAB);
uint64_t strTabAddr = des.GetSecAddr(ElfSecName::STRTAB);
RelocateTextInfo relaText = {textAddr, relatextAddr, relaTextSize};
SymAndStrTabInfo symAndStrTabInfo = {symTabAddr, symTabSize, strTabAddr, strTabSize};
Relocator relocate(relaText, symAndStrTabInfo);
#ifndef NDEBUG
relocate.DumpRelocateText();
#endif
relocate.RelocateBySymbol(symbol, patchAddr);
}
}
#endif
}
bool AnFileInfo::Load(const std::string &filename)
{
std::string realPath;
@ -355,7 +391,7 @@ void AOTFileManager::LoadStubFile(const std::string &fileName)
void AOTFileManager::LoadAnFile(const std::string &fileName)
{
AnFileDataManager *anFileDataManager = AnFileDataManager::GetInstance();
if (!anFileDataManager->SafeLoad(fileName, AnFileDataManager::Type::AOT)) {
if (!anFileDataManager->SafeLoad(fileName, AnFileDataManager::Type::AOT, vm_)) {
return;
}
}
@ -790,7 +826,7 @@ void AnFileDataManager::SafeDestoryAllData()
loadedAn_.clear();
}
bool AnFileDataManager::SafeLoad(const std::string &fileName, Type type)
bool AnFileDataManager::SafeLoad(const std::string &fileName, Type type, EcmaVM* vm)
{
os::memory::WriteLockHolder lock(lock_);
if (type == Type::STUB) {
@ -803,7 +839,7 @@ bool AnFileDataManager::SafeLoad(const std::string &fileName, Type type)
if (aotFileInfo != nullptr) {
return true;
}
return UnsafeLoadFromAOT(fileName);
return UnsafeLoadFromAOT(fileName, vm);
}
}
@ -830,7 +866,7 @@ bool AnFileDataManager::UnsafeLoadFromStub()
return true;
}
bool AnFileDataManager::UnsafeLoadFromAOT(const std::string &fileName)
bool AnFileDataManager::UnsafeLoadFromAOT(const std::string &fileName, EcmaVM *vm)
{
// note: This method is not thread-safe
// need to ensure that the instance of AnFileDataManager has been locked before use
@ -838,6 +874,7 @@ bool AnFileDataManager::UnsafeLoadFromAOT(const std::string &fileName)
if (!info->Load(fileName)) {
return false;
}
info->RewriteRelcateDeoptHandler(vm);
std::string anBasename = JSFilePath::GetBaseName(fileName);
anFileNameToIndexMap_.insert({anBasename, loadedAn_.size()});
loadedAn_.emplace_back(info);

View File

@ -376,6 +376,8 @@ public:
return isLoad_;
}
void RewriteRelcateDeoptHandler(EcmaVM *vm);
private:
bool Load(const std::string &filename);
void RewriteRelcateTextSection(const char* symbol, uintptr_t patchAddr);
@ -467,7 +469,7 @@ public:
static AnFileDataManager *GetInstance();
~AnFileDataManager();
bool SafeLoad(const std::string &fileName, Type type);
bool SafeLoad(const std::string &fileName, Type type, EcmaVM *vm = nullptr);
uint32_t SafeGetFileInfoIndex(const std::string &fileName);
std::shared_ptr<AnFileInfo> SafeGetAnFileInfo(uint32_t index);
std::shared_ptr<StubFileInfo> SafeGetStubFileInfo();
@ -501,7 +503,7 @@ public:
public:
AnFileDataManager() = default;
std::shared_ptr<AnFileInfo> UnsafeFind(const std::string &fileName) const;
bool UnsafeLoadFromAOT(const std::string &fileName);
bool UnsafeLoadFromAOT(const std::string &fileName, EcmaVM *vm);
bool UnsafeLoadFromStub();
os::memory::RWLock lock_;
@ -552,6 +554,12 @@ public:
std::string GetAotFileName(EcmaVM *vm, const JSPandaFile *jsPandaFile, const std::string &extensionName) const;
private:
void RewriteRelcateDeoptHandler(EcmaVM *vm, AnFileInfo AOTFileInfo)
{
AOTFileInfo.RewriteRelcateDeoptHandler(vm);
}
void PrintAOTEntry(const JSPandaFile *file, const Method *method, uintptr_t entry);
void InitializeStubEntries(const std::vector<AnFileInfo::FuncEntryDes>& stubs);
void AdjustBCStubAndDebuggerStubEntries(JSThread *thread, const std::vector<AOTFileInfo::FuncEntryDes> &stubs,

View File

@ -1654,12 +1654,11 @@ DEF_CALL_SIGNATURE(CreateArrayFromList)
DEF_CALL_SIGNATURE(DeoptHandlerAsm)
{
// 1 : 1 input parameters
CallSignature deoptHandlerAsm("DeoptHandlerAsm", 0, 2,
CallSignature deoptHandlerAsm("DeoptHandlerAsm", 0, 1,
ArgumentsOrder::DEFAULT_ORDER, VariableType::JS_ANY());
*callSign = deoptHandlerAsm;
std::array<VariableType, 2> params = { // 2 : 2 input parameters
std::array<VariableType, 1> params = { // 1 : 1 input parameters
VariableType::NATIVE_POINTER(), // glue
VariableType::NATIVE_POINTER(), // deoptType
};
callSign->SetVariadicArgs(false);
callSign->SetParameters(params.data());

View File

@ -332,7 +332,7 @@ void LLVMIRBuilder::GenPrologue()
reservedSlotsSize = OptimizedFrame::ComputeReservedSize(slotSize_);
LLVMAddTargetDependentFunctionAttr(function_, "frame-reserved-slots",
std::to_string(reservedSlotsSize).c_str());
SaveFrameTypeOnFrame(frameType, builder_);
SaveFrameTypeOnFrame(frameType);
} else if (frameType == FrameType::OPTIMIZED_JS_FUNCTION_FRAME) {
reservedSlotsSize = OptimizedJSFunctionFrame::ComputeReservedEnvOffset(slotSize_);
LLVMAddTargetDependentFunctionAttr(function_, "frame-reserved-slots",
@ -346,7 +346,7 @@ void LLVMIRBuilder::GenPrologue()
SaveLexicalEnvOnOptJSFuncFrame(value);
} else if (argth == static_cast<int>(CommonArgIdx::FUNC)) {
SaveJSFuncOnOptJSFuncFrame(value);
SaveFrameTypeOnFrame(frameType, builder_);
SaveFrameTypeOnFrame(frameType);
}
}
} else {
@ -355,15 +355,15 @@ void LLVMIRBuilder::GenPrologue()
}
}
void LLVMIRBuilder::SaveFrameTypeOnFrame(FrameType frameType, LLVMBuilderRef builder)
void LLVMIRBuilder::SaveFrameTypeOnFrame(FrameType frameType)
{
LLVMValueRef llvmFpAddr = CallingFp(module_, builder, false);
LLVMValueRef llvmFpAddr = CallingFp(module_, builder_, false);
LLVMValueRef frameAddr = LLVMBuildPtrToInt(builder, llvmFpAddr, slotType_, "cast_int_t");
LLVMValueRef frameTypeSlotAddr = LLVMBuildSub(builder, frameAddr, LLVMConstInt(slotType_, slotSize_, false), "");
LLVMValueRef addr = LLVMBuildIntToPtr(builder, frameTypeSlotAddr, LLVMPointerType(slotType_, 0), "frameType.Addr");
LLVMValueRef frameAddr = LLVMBuildPtrToInt(builder_, llvmFpAddr, slotType_, "cast_int_t");
LLVMValueRef frameTypeSlotAddr = LLVMBuildSub(builder_, frameAddr, LLVMConstInt(slotType_, slotSize_, false), "");
LLVMValueRef addr = LLVMBuildIntToPtr(builder_, frameTypeSlotAddr, LLVMPointerType(slotType_, 0), "frameType.Addr");
LLVMValueRef llvmFrameType = LLVMConstInt(slotType_, static_cast<uintptr_t>(frameType), 0);
LLVMBuildStore(builder, llvmFrameType, addr);
LLVMBuildStore(builder_, llvmFrameType, addr);
}
LLVMValueRef LLVMIRBuilder::CallingFp(LLVMModuleRef &module, LLVMBuilderRef &builder, bool isCaller)
@ -1961,44 +1961,6 @@ LLVMTypeRef LLVMIRBuilder::GetExperimentalDeoptTy()
return fnTy;
}
LLVMValueRef LLVMModule::GetDeoptFunction()
{
auto fn = LLVMGetNamedFunction(module_, LLVM_DEOPT_RELOCATE_SYMBOL);
return fn;
}
void LLVMIRBuilder::GenDeoptEntry(LLVMModuleRef &module)
{
std::vector<LLVMTypeRef> paramTys = {LLVMInt64Type(), LLVMInt64Type()}; // glue type
auto funcType = LLVMFunctionType(LLVMInt64Type(), paramTys.data(), paramTys.size(), 0);
auto Function = LLVMAddFunction(module, LLVM_DEOPT_RELOCATE_SYMBOL, funcType);
LLVMSetFunctionCallConv(Function, LLVMCCallConv);
LLVMBasicBlockRef entry = LLVMAppendBasicBlock(Function, "entry");
LLVMBuilderRef builder = LLVMCreateBuilder();
LLVMPositionBuilderAtEnd(builder, entry);
auto reservedSlotsSize = OptimizedFrame::ComputeReservedSize(slotSize_);
LLVMAddTargetDependentFunctionAttr(Function, "frame-reserved-slots",
std::to_string(reservedSlotsSize).c_str());
SaveFrameTypeOnFrame(FrameType::OPTIMIZED_FRAME, builder);
LLVMValueRef glue = LLVMGetParam(Function, 0);
LLVMValueRef check = LLVMGetParam(Function, 1);
StubIdType stubId = RTSTUB_ID(DeoptHandlerAsm);
int stubIndex = static_cast<int>(std::get<RuntimeStubCSigns::ID>(stubId));
LLVMValueRef rtoffset = LLVMBuildAdd(builder, glue, GetRTStubOffset(glue, stubIndex), "");
LLVMValueRef patchAddr = LLVMBuildIntToPtr(builder, rtoffset, LLVMPointerType(LLVMInt64Type(), 0), "");
LLVMValueRef llvmAddr = LLVMBuildLoad(builder, patchAddr, "");
LLVMTypeRef rtfuncTypePtr = LLVMPointerType(funcType, 0);
LLVMValueRef callee = LLVMBuildIntToPtr(builder, llvmAddr, rtfuncTypePtr, "");
std::vector<LLVMValueRef> params = {glue, check};
LLVMValueRef runtimeCall = LLVMBuildCall2(builder, funcType, callee, params.data(), params.size(), "");
LLVMBuildRet(builder, runtimeCall);
LLVMPositionBuilderAtEnd(builder, entry);
}
LLVMValueRef LLVMIRBuilder::GetExperimentalDeopt(LLVMModuleRef &module)
{
/* 0:calling 1:its caller */
@ -2006,7 +1968,6 @@ LLVMValueRef LLVMIRBuilder::GetExperimentalDeopt(LLVMModuleRef &module)
if (!fn) {
auto fnTy = GetExperimentalDeoptTy();
fn = LLVMAddFunction(module, "llvm.experimental.deoptimize.p1i64", fnTy);
GenDeoptEntry(module);
}
return fn;
}

View File

@ -169,7 +169,6 @@ public:
{
return callSigns_;
}
LLVMValueRef GetDeoptFunction();
private:
LLVMValueRef AddAndGetFunc(const CallSignature *stubDescriptor);
void InitialLLVMFuncTypeAndFuncByModuleCSigns();
@ -335,11 +334,10 @@ private:
CallExceptionKind kind);
void SaveLexicalEnvOnOptJSFuncFrame(LLVMValueRef value);
void SaveJSFuncOnOptJSFuncFrame(LLVMValueRef value);
void SaveFrameTypeOnFrame(FrameType frameType, LLVMBuilderRef builder);
void SaveFrameTypeOnFrame(FrameType frameType);
void UpdateLeaveFrame(LLVMValueRef glue);
LLVMTypeRef GetExperimentalDeoptTy();
LLVMValueRef GetExperimentalDeopt(LLVMModuleRef &module);
void GenDeoptEntry(LLVMModuleRef &module);
const CompilationConfig *compCfg_ {nullptr};
const std::vector<std::vector<GateRef>> *scheduledGates_ {nullptr};
const Circuit *circuit_ {nullptr};

View File

@ -105,58 +105,10 @@ void Deoptimizier::CollectVregs(const std::vector<kungfu::ARKDeopt>& deoptBundle
}
}
// when AOT trigger deopt, frame layout as the following
// * OptimizedJSFunctionFrame layout description as the following:
// +--------------------------+ ---------------
// | ...... | ^
// | ...... | callerFunction
// | ...... | |
// |--------------------------| |
// | args | v
// +--------------------------+ ---------------
// | returnAddr | ^
// |--------------------------| |
// | callsiteFp | |
// |--------------------------| OptimizedJSFunction FrameType:OptimizedJSFunctionFrame
// | frameType | |
// |--------------------------| |
// | call-target | |
// |--------------------------| |
// | lexEnv | |
// |--------------------------| |
// | ........... | v
// +--------------------------+ ---------------
// | returnAddr | ^
// |--------------------------| |
// | callsiteFp | |
// |--------------------------| __llvm_deoptimize FrameType:OPTIMIZED_FRAME
// | frameType | |
// |--------------------------| |
// | No CalleeSave | |
// | Registers | v
// +--------------------------+ ---------------
// | returnAddr | ^
// |--------------------------| |
// | callsiteFp | |
// |--------------------------| DeoptHandlerAsm FrameType:OPTIMIZED_FRAME
// | frameType | |
// |--------------------------| |
// | glue | |
// |--------------------------| |
// | CalleeSave Registers | v
// +--------------------------+ ---------------
// | ......... | ^
// | ......... | CallRuntime FrameType:OptimizedLeaveFrame
// | ......... | |
// | ......... | v
// |--------------------------| ---------------
void Deoptimizier::CollectDeoptBundleVec(std::vector<kungfu::ARKDeopt>& deoptBundle)
{
JSTaggedType *lastLeave = const_cast<JSTaggedType *>(thread_->GetLastLeaveFrame());
FrameIterator it(lastLeave, thread_);
// note: last optimized frame is generated by DeoptHandlerAsm, callee Regs is grow from this frame
bool deoptEnterAsmFlag = true;
for (; !it.Done() && deoptBundle.empty(); it.Advance<GCVisitedFlag::VISITED>()) {
FrameType type = it.GetFrameType();
switch (type) {
@ -179,12 +131,8 @@ void Deoptimizier::CollectDeoptBundleVec(std::vector<kungfu::ARKDeopt>& deoptBun
}
case FrameType::OPTIMIZED_FRAME: {
auto sp = reinterpret_cast<uintptr_t*>(it.GetSp());
if (deoptEnterAsmFlag) {
static constexpr size_t TYPE_GLUE_SLOT = 2; // 2: skip type & glue
sp -= TYPE_GLUE_SLOT;
calleeRegAddr_ = sp - numCalleeRegs_;
deoptEnterAsmFlag = false;
}
sp -= 2; // 2: skip type & glue
calleeRegAddr_ = sp - numCalleeRegs_;
break;
}
case FrameType::LEAVE_FRAME:

View File

@ -0,0 +1,175 @@
/*
* Copyright (c) 2022 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.
*/
#include "ecmascript/deoptimizer/relocator.h"
#include <climits>
#include <iomanip>
#include "ecmascript/compiler/assembler/aarch64/assembler_aarch64_constants.h"
#include "ecmascript/message_string.h"
#if !WIN_OR_MAC_OR_IOS_PLATFORM
namespace panda::ecmascript {
std::optional<Elf64_Word> Relocator::GetSymbol(const char* symbol) const
{
ASSERT(symAndStrTabInfo_.symSize_ % sizeof(Elf64_Sym) == 0);
int n = symAndStrTabInfo_.symSize_ / sizeof(Elf64_Sym);
ASSERT(symAndStrTabInfo_.symAddr_ > 0 && symAndStrTabInfo_.symSize_ > 0);
Elf64_Sym *ptr = reinterpret_cast<Elf64_Sym *>(symAndStrTabInfo_.symAddr_);
for (int i = 0; i < n; i++) {
Elf64_Sym *cur = ptr + i;
const char *name = reinterpret_cast<char *>(symAndStrTabInfo_.strAddr_) + cur->st_name;
if (std::strcmp(symbol, name) == 0) {
return static_cast<Elf64_Word>(i);
}
}
return std::nullopt;
}
bool Relocator::Relocate(Elf64_Rela *sec, uintptr_t symbolAddr, uintptr_t patchAddr)
{
bool ret = false;
ASSERT(reinterpret_cast<intptr_t>(sec) > 0);
Elf64_Word type = GetType(sec);
Elf64_Sxword addend = sec->r_addend;
switch (type) {
case R_AARCH64_CALL26: {
/* S + A - P
S: (when used on its own) is the address of the symbol
A: is the addend for the relocation
P: is the address of the place beging relocated(derived from r_offset)
*/
intptr_t imm = patchAddr + addend - symbolAddr;
ASSERT(-(1 << 27) <= imm && imm < (1 << 27)); // 27: "Check that -2^27 <= result < 2^27".
imm = (imm & 0x0FFFFFFC) >> 2; // 0x0FFFFFFC: get immediate file to bits [27:2]
*(reinterpret_cast<uint32_t *>(symbolAddr)) = imm | panda::ecmascript::aarch64::CallOpCode::BL;
break;
}
case R_X86_64_PLT32: {
/* S + A - P
S: (when used on its own) is the address of the symbol
A: is the addend for the relocation
P: is the address of the place beging relocated(derived from r_offset)
*/
intptr_t v = patchAddr + addend - symbolAddr;
ASSERT((v >= INT_MIN) && (v <= INT_MAX));
*(reinterpret_cast<uint32_t *>(symbolAddr)) = v;
ret = true;
break;
}
default: {
LOG_COMPILER(FATAL) << " unsupported type:" << type;
return false;
}
}
return ret;
}
bool Relocator::HasSymStrTable() const
{
return (symAndStrTabInfo_.symAddr_ >= 0) && (symAndStrTabInfo_.symSize_ >= 0) &&
(symAndStrTabInfo_.strAddr_ >= 0) && (symAndStrTabInfo_.strSize_ >= 0);
}
bool Relocator::HasRelocateText() const
{
return (relocateTextInfo_.relaTextAddr_ > 0) && (relocateTextInfo_.relaTextSize_ > 0);
}
bool Relocator::RelocateBySymbolId(Elf64_Word symbolId, uintptr_t patchAddr)
{
bool ret = false;
ASSERT(relocateTextInfo_.relaTextSize_ % sizeof(Elf64_Rela) == 0);
ASSERT(relocateTextInfo_.relaTextAddr_ > 0 && relocateTextInfo_.relaTextSize_ > 0);
size_t n = relocateTextInfo_.relaTextSize_ / sizeof(Elf64_Rela);
Elf64_Rela *ptr = reinterpret_cast<Elf64_Rela *>(relocateTextInfo_.relaTextAddr_);
for (size_t i = 0; i < n; i++) {
Elf64_Rela *cur = ptr + i;
Elf64_Word id = GetSymbol(cur);
intptr_t symbolAddr = relocateTextInfo_.textAddr_ + static_cast<uintptr_t>(cur->r_offset);
if (id == symbolId) {
ret = Relocate(cur, symbolAddr, patchAddr);
}
}
return ret;
}
bool Relocator::RelocateBySymbol(const char* symbol, uintptr_t patchAddr)
{
if (!HasSymStrTable()) {
return false;
}
auto symId = GetSymbol(symbol);
if (!symId.has_value()) {
LOG_COMPILER(DEBUG) << " don't find symbol:" << symbol << " in symbol table.";
return false;
}
bool ret = RelocateBySymbolId(symId.value(), patchAddr);
return ret;
}
void Relocator::DumpRelocateText()
{
if (!HasRelocateText()) {
LOG_COMPILER(ERROR) << " input valid relocateText addr & size:";
return;
}
ASSERT(relocateTextInfo_.relaTextSize_ % sizeof(Elf64_Rela) == 0);
ASSERT(relocateTextInfo_.relaTextAddr_ > 0 && relocateTextInfo_.relaTextSize_ > 0);
size_t n = relocateTextInfo_.relaTextSize_ / sizeof(Elf64_Rela);
Elf64_Rela *ptr = reinterpret_cast<Elf64_Rela *>(relocateTextInfo_.relaTextAddr_);
static constexpr int leftAdjustment = 12;
LOG_COMPILER(DEBUG) << std::left << std::setw(leftAdjustment) << "symbolId "
<< std::left << std::setw(leftAdjustment) << "Info(0x): "
<< std::left << std::setw(leftAdjustment) << "Type: "
<< std::left << std::setw(leftAdjustment) << "r_offset(0x): "
<< std::left << std::setw(leftAdjustment) << "addend: ";
for (size_t i = 0; i < n; i++) {
Elf64_Rela *cur = ptr + i;
Elf64_Word id = GetSymbol(cur);
Elf64_Word type = GetType(cur);
Elf64_Sxword addend = ptr->r_addend;
LOG_COMPILER(DEBUG) << std::left << std::setw(leftAdjustment) << id
<< std::left << std::setw(leftAdjustment) << std::hex << cur->r_info
<< std::left << std::setw(leftAdjustment) << std::dec << type
<< std::left << std::setw(leftAdjustment) << std::hex << static_cast<intptr_t>(cur->r_offset)
<< std::left << std::setw(leftAdjustment) << std::dec << static_cast<intptr_t>(addend);
}
if (!HasSymStrTable()) {
return;
}
ASSERT(symAndStrTabInfo_.symSize_ % sizeof(Elf64_Sym) == 0);
n = symAndStrTabInfo_.symSize_ / sizeof(Elf64_Sym);
ASSERT(symAndStrTabInfo_.symAddr_ > 0 && symAndStrTabInfo_.symSize_ > 0);
Elf64_Sym *symPtr = reinterpret_cast<Elf64_Sym *>(symAndStrTabInfo_.symAddr_);
LOG_COMPILER(DEBUG) << std::left << std::setw(leftAdjustment) << "symbolId "
<< std::left << std::setw(leftAdjustment) << "binding: "
<< std::left << std::setw(leftAdjustment) << "Type: "
<< std::left << std::setw(leftAdjustment) << "st_name: "
<< std::left << std::setw(leftAdjustment) << "name: ";
for (size_t i = 0; i < n; i++) {
Elf64_Sym *cur = symPtr + i;
const char *name = reinterpret_cast<char *>(symAndStrTabInfo_.strAddr_) + cur->st_name;
unsigned char binding = GetBinding(cur);
unsigned char type = GetType(cur);
LOG_COMPILER(DEBUG) << std::left << std::setw(leftAdjustment) << i
<< std::left << std::setw(leftAdjustment) << std::dec << static_cast<int>(binding)
<< std::left << std::setw(leftAdjustment) << std::dec << static_cast<int>(type)
<< std::left << std::setw(leftAdjustment) << std::dec << cur->st_name
<< std::left << std::setw(leftAdjustment) << name;
}
}
} // namespace panda::ecmascript
#endif

View File

@ -0,0 +1,84 @@
/*
* Copyright (c) 2022 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.
*/
#ifndef ECMASCRIPT_DEOPTIMIZER_RELCATOR_H
#define ECMASCRIPT_DEOPTIMIZER_RELCATOR_H
#include "ecmascript/common.h"
#if !WIN_OR_MAC_OR_IOS_PLATFORM
#include <elf.h>
#include <optional>
#include "ecmascript/ecma_macros.h"
namespace panda::ecmascript {
struct RelocateTextInfo {
uintptr_t textAddr_ {0};
uintptr_t relaTextAddr_ {0};
uintptr_t relaTextSize_ {0};
};
struct SymAndStrTabInfo {
uintptr_t symAddr_ {0};
uintptr_t symSize_ {0};
uintptr_t strAddr_ {0};
uintptr_t strSize_ {0};
};
class Relocator {
public:
PUBLIC_API Relocator(RelocateTextInfo relaText, SymAndStrTabInfo symAndStrTabInfo)
:relocateTextInfo_(relaText), symAndStrTabInfo_(symAndStrTabInfo) {};
PUBLIC_API bool RelocateBySymbolId(Elf64_Word symbolId, uintptr_t patchAddr);
PUBLIC_API bool RelocateBySymbol(const char* symbol, uintptr_t patchAddr);
PUBLIC_API void DumpRelocateText();
~Relocator() = default;
private:
bool HasSymStrTable() const;
bool HasRelocateText() const;
std::optional<Elf64_Word> GetSymbol(const char* symbol) const;
bool Relocate(Elf64_Rela *sec, uintptr_t symbolAddr, uintptr_t patchAddr);
Elf64_Word GetSymbol(Elf64_Rela *cur) const
{
Elf64_Word id = (cur->r_info >> 32); // 32: get high 32 bits
return id;
}
Elf64_Word GetType(Elf64_Rela *cur) const
{
return (cur->r_info & 0xffffffffL); // 0xffffffff :get lower 32 bits
}
// These accessors and mutators are identical to those defined for ELF32
// symbol table entries.
unsigned char GetBinding(Elf64_Sym *cur) const
{
return cur->st_info >> 4; // 4: offset
}
unsigned char GetType(Elf64_Sym *cur) const
{
return cur->st_info & 0x0f; // f: get lowest 4 bits
}
RelocateTextInfo relocateTextInfo_ {0};
SymAndStrTabInfo symAndStrTabInfo_ {0};
};
} // panda::ecmascript
#endif
#endif // ECMASCRIPT_DEOPTIMIZER_RELCATOR_H