mirror of
https://gitee.com/openharmony/arkcompiler_ets_runtime
synced 2024-10-07 08:03:29 +00:00
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:
parent
5f56827f75
commit
dac99d6453
1
BUILD.gn
1
BUILD.gn
@ -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",
|
||||
|
@ -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);
|
||||
|
@ -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,
|
||||
|
@ -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());
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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};
|
||||
|
@ -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:
|
||||
|
175
ecmascript/deoptimizer/relocator.cpp
Normal file
175
ecmascript/deoptimizer/relocator.cpp
Normal 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
|
84
ecmascript/deoptimizer/relocator.h
Normal file
84
ecmascript/deoptimizer/relocator.h
Normal 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
|
||||
|
Loading…
Reference in New Issue
Block a user