forked from OSchip/llvm-project
[ORC] Replace MachOJITDylibInitializers::SectionExtent with ExecutorAddressRange
MachOJITDylibInitializers::SectionExtent represented the address range of a section as an (address, size) pair. The new ExecutorAddressRange type generalizes this to an address range (for any object, not necessarily a section) represented as a (start-address, end-address) pair. The aim is to express more of ORC (and the ORC runtime) in terms of simple types that can be serialized/deserialized via SPS. This will simplify SPS-based RPC involving arguments/return-values of these types.
This commit is contained in:
parent
88efb59b78
commit
5471766f9d
|
@ -17,6 +17,7 @@
|
|||
#include "llvm/ExecutionEngine/Orc/Core.h"
|
||||
#include "llvm/ExecutionEngine/Orc/ExecutionUtils.h"
|
||||
#include "llvm/ExecutionEngine/Orc/ObjectLinkingLayer.h"
|
||||
#include "llvm/ExecutionEngine/Orc/Shared/CommonOrcRuntimeTypes.h"
|
||||
|
||||
#include <future>
|
||||
#include <thread>
|
||||
|
@ -31,21 +32,13 @@ bool objCRegistrationEnabled();
|
|||
|
||||
class MachOJITDylibInitializers {
|
||||
public:
|
||||
struct SectionExtent {
|
||||
SectionExtent() = default;
|
||||
SectionExtent(JITTargetAddress Address, uint64_t NumPtrs)
|
||||
: Address(Address), NumPtrs(NumPtrs) {}
|
||||
JITTargetAddress Address = 0;
|
||||
uint64_t NumPtrs = 0;
|
||||
};
|
||||
|
||||
using RawPointerSectionList = std::vector<SectionExtent>;
|
||||
using RawPointerSectionList = std::vector<shared::ExecutorAddressRange>;
|
||||
|
||||
void setObjCImageInfoAddr(JITTargetAddress ObjCImageInfoAddr) {
|
||||
this->ObjCImageInfoAddr = ObjCImageInfoAddr;
|
||||
}
|
||||
|
||||
void addModInitsSection(SectionExtent ModInit) {
|
||||
void addModInitsSection(shared::ExecutorAddressRange ModInit) {
|
||||
ModInitSections.push_back(std::move(ModInit));
|
||||
}
|
||||
|
||||
|
@ -53,7 +46,7 @@ public:
|
|||
return ModInitSections;
|
||||
}
|
||||
|
||||
void addObjCSelRefsSection(SectionExtent ObjCSelRefs) {
|
||||
void addObjCSelRefsSection(shared::ExecutorAddressRange ObjCSelRefs) {
|
||||
ObjCSelRefsSections.push_back(std::move(ObjCSelRefs));
|
||||
}
|
||||
|
||||
|
@ -61,7 +54,7 @@ public:
|
|||
return ObjCSelRefsSections;
|
||||
}
|
||||
|
||||
void addObjCClassListSection(SectionExtent ObjCClassList) {
|
||||
void addObjCClassListSection(shared::ExecutorAddressRange ObjCClassList) {
|
||||
ObjCClassListSections.push_back(std::move(ObjCClassList));
|
||||
}
|
||||
|
||||
|
@ -152,9 +145,9 @@ private:
|
|||
};
|
||||
|
||||
void registerInitInfo(JITDylib &JD, JITTargetAddress ObjCImageInfoAddr,
|
||||
MachOJITDylibInitializers::SectionExtent ModInits,
|
||||
MachOJITDylibInitializers::SectionExtent ObjCSelRefs,
|
||||
MachOJITDylibInitializers::SectionExtent ObjCClassList);
|
||||
shared::ExecutorAddressRange ModInits,
|
||||
shared::ExecutorAddressRange ObjCSelRefs,
|
||||
shared::ExecutorAddressRange ObjCClassList);
|
||||
|
||||
ExecutionSession &ES;
|
||||
ObjectLinkingLayer &ObjLinkingLayer;
|
||||
|
|
|
@ -0,0 +1,66 @@
|
|||
//===------------------- CommonOrcRuntimeTypes.h ----------------*- C++ -*-===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Generic types usable with SPS and the ORC runtime.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_EXECUTIONENGINE_ORC_SHARED_COMMONORCRUNTIMETYPES_H
|
||||
#define LLVM_EXECUTIONENGINE_ORC_SHARED_COMMONORCRUNTIMETYPES_H
|
||||
|
||||
#include "llvm/ExecutionEngine/Orc/Shared/SimplePackedSerialization.h"
|
||||
|
||||
namespace llvm {
|
||||
namespace orc {
|
||||
namespace shared {
|
||||
|
||||
/// Represents an address range in the exceutor process.
|
||||
struct ExecutorAddressRange {
|
||||
ExecutorAddressRange() = default;
|
||||
ExecutorAddressRange(JITTargetAddress StartAddress,
|
||||
JITTargetAddress EndAddress)
|
||||
: StartAddress(StartAddress), EndAddress(EndAddress) {}
|
||||
|
||||
bool empty() const { return StartAddress == EndAddress; }
|
||||
size_t size() const { return EndAddress - StartAddress; }
|
||||
|
||||
JITTargetAddress StartAddress = 0;
|
||||
JITTargetAddress EndAddress = 0;
|
||||
};
|
||||
|
||||
using SPSExecutorAddressRange =
|
||||
SPSTuple<SPSExecutorAddress, SPSExecutorAddress>;
|
||||
|
||||
/// Serialization traits for address ranges.
|
||||
template <>
|
||||
class SPSSerializationTraits<SPSExecutorAddressRange, ExecutorAddressRange> {
|
||||
public:
|
||||
static size_t size(const ExecutorAddressRange &Value) {
|
||||
return SPSArgList<SPSExecutorAddress, SPSExecutorAddress>::size(
|
||||
Value.StartAddress, Value.EndAddress);
|
||||
}
|
||||
|
||||
static bool serialize(SPSOutputBuffer &BOB,
|
||||
const ExecutorAddressRange &Value) {
|
||||
return SPSArgList<SPSExecutorAddress, SPSExecutorAddress>::serialize(
|
||||
BOB, Value.StartAddress, Value.EndAddress);
|
||||
}
|
||||
|
||||
static bool deserialize(SPSInputBuffer &BIB, ExecutorAddressRange &Value) {
|
||||
return SPSArgList<SPSExecutorAddress, SPSExecutorAddress>::deserialize(
|
||||
BIB, Value.StartAddress, Value.EndAddress);
|
||||
}
|
||||
};
|
||||
|
||||
using SPSExecutorAddressRangeSequence = SPSSequence<SPSExecutorAddressRange>;
|
||||
|
||||
} // End namespace shared.
|
||||
} // End namespace orc.
|
||||
} // End namespace llvm.
|
||||
|
||||
#endif // LLVM_EXECUTIONENGINE_ORC_SHARED_COMMONORCRUNTIMETYPES_H
|
|
@ -88,11 +88,15 @@ bool objCRegistrationEnabled() {
|
|||
|
||||
void MachOJITDylibInitializers::runModInits() const {
|
||||
for (const auto &ModInit : ModInitSections) {
|
||||
for (uint64_t I = 0; I != ModInit.NumPtrs; ++I) {
|
||||
auto *InitializerAddr = jitTargetAddressToPointer<uintptr_t *>(
|
||||
ModInit.Address + (I * sizeof(uintptr_t)));
|
||||
auto *Initializer =
|
||||
jitTargetAddressToFunction<void (*)()>(*InitializerAddr);
|
||||
assert(ModInit.size() % sizeof(uintptr_t) == 0 &&
|
||||
"ModInit section size is not a pointer multiple?");
|
||||
for (uintptr_t *
|
||||
InitPtr =
|
||||
jitTargetAddressToPointer<uintptr_t *>(ModInit.StartAddress),
|
||||
*InitEnd =
|
||||
jitTargetAddressToPointer<uintptr_t *>(ModInit.EndAddress);
|
||||
InitPtr != InitEnd; ++InitPtr) {
|
||||
auto *Initializer = reinterpret_cast<void (*)()>(*InitPtr);
|
||||
Initializer();
|
||||
}
|
||||
}
|
||||
|
@ -102,8 +106,11 @@ void MachOJITDylibInitializers::registerObjCSelectors() const {
|
|||
assert(objCRegistrationEnabled() && "ObjC registration not enabled.");
|
||||
|
||||
for (const auto &ObjCSelRefs : ObjCSelRefsSections) {
|
||||
for (uint64_t I = 0; I != ObjCSelRefs.NumPtrs; ++I) {
|
||||
auto SelEntryAddr = ObjCSelRefs.Address + (I * sizeof(uintptr_t));
|
||||
assert(ObjCSelRefs.size() % sizeof(uintptr_t) == 0 &&
|
||||
"ObjCSelRefs section size is not a pointer multiple?");
|
||||
for (JITTargetAddress SelEntryAddr = ObjCSelRefs.StartAddress;
|
||||
SelEntryAddr != ObjCSelRefs.EndAddress;
|
||||
SelEntryAddr += sizeof(uintptr_t)) {
|
||||
const auto *SelName =
|
||||
*jitTargetAddressToPointer<const char **>(SelEntryAddr);
|
||||
auto Sel = sel_registerName(SelName);
|
||||
|
@ -128,8 +135,11 @@ Error MachOJITDylibInitializers::registerObjCClasses() const {
|
|||
auto ClassSelector = sel_registerName("class");
|
||||
|
||||
for (const auto &ObjCClassList : ObjCClassListSections) {
|
||||
for (uint64_t I = 0; I != ObjCClassList.NumPtrs; ++I) {
|
||||
auto ClassPtrAddr = ObjCClassList.Address + (I * sizeof(uintptr_t));
|
||||
assert(ObjCClassList.size() % sizeof(uintptr_t) == 0 &&
|
||||
"ObjCClassList section size is not a pointer multiple?");
|
||||
for (JITTargetAddress ClassPtrAddr = ObjCClassList.StartAddress;
|
||||
ClassPtrAddr != ObjCClassList.EndAddress;
|
||||
ClassPtrAddr += sizeof(uintptr_t)) {
|
||||
auto Cls = *jitTargetAddressToPointer<Class *>(ClassPtrAddr);
|
||||
auto *ClassCompiled =
|
||||
*jitTargetAddressToPointer<ObjCClassCompiled **>(ClassPtrAddr);
|
||||
|
@ -264,37 +274,36 @@ MachOPlatform::getDeinitializerSequence(JITDylib &JD) {
|
|||
|
||||
void MachOPlatform::registerInitInfo(
|
||||
JITDylib &JD, JITTargetAddress ObjCImageInfoAddr,
|
||||
MachOJITDylibInitializers::SectionExtent ModInits,
|
||||
MachOJITDylibInitializers::SectionExtent ObjCSelRefs,
|
||||
MachOJITDylibInitializers::SectionExtent ObjCClassList) {
|
||||
shared::ExecutorAddressRange ModInits,
|
||||
shared::ExecutorAddressRange ObjCSelRefs,
|
||||
shared::ExecutorAddressRange ObjCClassList) {
|
||||
std::lock_guard<std::mutex> Lock(InitSeqsMutex);
|
||||
|
||||
auto &InitSeq = InitSeqs[&JD];
|
||||
|
||||
InitSeq.setObjCImageInfoAddr(ObjCImageInfoAddr);
|
||||
|
||||
if (ModInits.Address)
|
||||
if (ModInits.StartAddress)
|
||||
InitSeq.addModInitsSection(std::move(ModInits));
|
||||
|
||||
if (ObjCSelRefs.Address)
|
||||
if (ObjCSelRefs.StartAddress)
|
||||
InitSeq.addObjCSelRefsSection(std::move(ObjCSelRefs));
|
||||
|
||||
if (ObjCClassList.Address)
|
||||
if (ObjCClassList.StartAddress)
|
||||
InitSeq.addObjCClassListSection(std::move(ObjCClassList));
|
||||
}
|
||||
|
||||
static Expected<MachOJITDylibInitializers::SectionExtent>
|
||||
static Expected<shared::ExecutorAddressRange>
|
||||
getSectionExtent(jitlink::LinkGraph &G, StringRef SectionName) {
|
||||
auto *Sec = G.findSectionByName(SectionName);
|
||||
if (!Sec)
|
||||
return MachOJITDylibInitializers::SectionExtent();
|
||||
return shared::ExecutorAddressRange();
|
||||
jitlink::SectionRange R(*Sec);
|
||||
if (R.getSize() % G.getPointerSize() != 0)
|
||||
return make_error<StringError>(SectionName + " section size is not a "
|
||||
"multiple of the pointer size",
|
||||
inconvertibleErrorCode());
|
||||
return MachOJITDylibInitializers::SectionExtent(
|
||||
R.getStart(), R.getSize() / G.getPointerSize());
|
||||
return shared::ExecutorAddressRange{R.getStart(), R.getEnd()};
|
||||
}
|
||||
|
||||
void MachOPlatform::InitScraperPlugin::modifyPassConfig(
|
||||
|
@ -326,8 +335,7 @@ void MachOPlatform::InitScraperPlugin::modifyPassConfig(
|
|||
|
||||
Config.PostFixupPasses.push_back([this, &JD = MR.getTargetJITDylib()](
|
||||
jitlink::LinkGraph &G) -> Error {
|
||||
MachOJITDylibInitializers::SectionExtent ModInits, ObjCSelRefs,
|
||||
ObjCClassList;
|
||||
shared::ExecutorAddressRange ModInits, ObjCSelRefs, ObjCClassList;
|
||||
|
||||
JITTargetAddress ObjCImageInfoAddr = 0;
|
||||
if (auto *ObjCImageInfoSec =
|
||||
|
@ -359,23 +367,26 @@ void MachOPlatform::InitScraperPlugin::modifyPassConfig(
|
|||
LLVM_DEBUG({
|
||||
dbgs() << "MachOPlatform: Scraped " << G.getName() << " init sections:\n";
|
||||
dbgs() << " __objc_selrefs: ";
|
||||
if (ObjCSelRefs.NumPtrs)
|
||||
dbgs() << ObjCSelRefs.NumPtrs << " pointer(s) at "
|
||||
<< formatv("{0:x16}", ObjCSelRefs.Address) << "\n";
|
||||
auto NumObjCSelRefs = ObjCSelRefs.size() / sizeof(uintptr_t);
|
||||
if (NumObjCSelRefs)
|
||||
dbgs() << NumObjCSelRefs << " pointer(s) at "
|
||||
<< formatv("{0:x16}", ObjCSelRefs.StartAddress) << "\n";
|
||||
else
|
||||
dbgs() << "none\n";
|
||||
|
||||
dbgs() << " __objc_classlist: ";
|
||||
if (ObjCClassList.NumPtrs)
|
||||
dbgs() << ObjCClassList.NumPtrs << " pointer(s) at "
|
||||
<< formatv("{0:x16}", ObjCClassList.Address) << "\n";
|
||||
auto NumObjCClasses = ObjCClassList.size() / sizeof(uintptr_t);
|
||||
if (NumObjCClasses)
|
||||
dbgs() << NumObjCClasses << " pointer(s) at "
|
||||
<< formatv("{0:x16}", ObjCClassList.StartAddress) << "\n";
|
||||
else
|
||||
dbgs() << "none\n";
|
||||
|
||||
dbgs() << " __mod_init_func: ";
|
||||
if (ModInits.NumPtrs)
|
||||
dbgs() << ModInits.NumPtrs << " pointer(s) at "
|
||||
<< formatv("{0:x16}", ModInits.Address) << "\n";
|
||||
auto NumModInits = ModInits.size() / sizeof(uintptr_t);
|
||||
if (NumModInits)
|
||||
dbgs() << NumModInits << " pointer(s) at "
|
||||
<< formatv("{0:x16}", ModInits.StartAddress) << "\n";
|
||||
else
|
||||
dbgs() << "none\n";
|
||||
});
|
||||
|
|
Loading…
Reference in New Issue