1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-10-18 10:32:48 +02:00

[ORC] Flesh out ExecutorAddress, rename CommonOrcRuntimeTypes header.

Renames CommonOrcRuntimeTypes.h to ExecutorAddress.h and moves ExecutorAddress
into the 'orc' namespace (rather than orc::shared).

Also makes ExecutorAddress a class, adds an ExecutorAddrDiff type and some
arithmetic operations on the pair (subtracting two addresses yields an addrdiff,
adding an addrdiff and an address yields an address).
This commit is contained in:
Lang Hames 2021-07-09 08:24:08 +10:00
parent 20f8f245ff
commit a6848c8034
4 changed files with 245 additions and 109 deletions

View File

@ -17,7 +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 "llvm/ExecutionEngine/Orc/Shared/ExecutorAddress.h"
#include <future>
#include <thread>
@ -32,13 +32,13 @@ bool objCRegistrationEnabled();
class MachOJITDylibInitializers {
public:
using RawPointerSectionList = std::vector<shared::ExecutorAddressRange>;
using RawPointerSectionList = std::vector<ExecutorAddressRange>;
void setObjCImageInfoAddr(JITTargetAddress ObjCImageInfoAddr) {
this->ObjCImageInfoAddr = ObjCImageInfoAddr;
}
void addModInitsSection(shared::ExecutorAddressRange ModInit) {
void addModInitsSection(ExecutorAddressRange ModInit) {
ModInitSections.push_back(std::move(ModInit));
}
@ -46,7 +46,7 @@ public:
return ModInitSections;
}
void addObjCSelRefsSection(shared::ExecutorAddressRange ObjCSelRefs) {
void addObjCSelRefsSection(ExecutorAddressRange ObjCSelRefs) {
ObjCSelRefsSections.push_back(std::move(ObjCSelRefs));
}
@ -54,7 +54,7 @@ public:
return ObjCSelRefsSections;
}
void addObjCClassListSection(shared::ExecutorAddressRange ObjCClassList) {
void addObjCClassListSection(ExecutorAddressRange ObjCClassList) {
ObjCClassListSections.push_back(std::move(ObjCClassList));
}
@ -145,9 +145,9 @@ private:
};
void registerInitInfo(JITDylib &JD, JITTargetAddress ObjCImageInfoAddr,
shared::ExecutorAddressRange ModInits,
shared::ExecutorAddressRange ObjCSelRefs,
shared::ExecutorAddressRange ObjCClassList);
ExecutorAddressRange ModInits,
ExecutorAddressRange ObjCSelRefs,
ExecutorAddressRange ObjCClassList);
ExecutionSession &ES;
ObjectLinkingLayer &ObjLinkingLayer;

View File

@ -1,68 +0,0 @@
//===------------------- 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 {
// Placeholder for future replacement for JITTargetAddress.
using ExecutorAddress = uint64_t;
/// Represents an address range in the exceutor process.
struct ExecutorAddressRange {
ExecutorAddressRange() = default;
ExecutorAddressRange(ExecutorAddress StartAddress, ExecutorAddress EndAddress)
: StartAddress(StartAddress), EndAddress(EndAddress) {}
bool empty() const { return StartAddress == EndAddress; }
size_t size() const { return EndAddress - StartAddress; }
ExecutorAddress StartAddress = 0;
ExecutorAddress 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

View File

@ -0,0 +1,203 @@
//===------ ExecutorAddress.h - Executing process address -------*- 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
//
//===----------------------------------------------------------------------===//
//
// Represents an address in the executing program.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_EXECUTIONENGINE_ORC_SHARED_EXECUTORADDRESS_H
#define LLVM_EXECUTIONENGINE_ORC_SHARED_EXECUTORADDRESS_H
#include "llvm/ExecutionEngine/Orc/Shared/SimplePackedSerialization.h"
#include <cassert>
#include <type_traits>
namespace llvm {
namespace orc {
/// Represents the difference between two addresses in the executor process.
class ExecutorAddrDiff {
public:
ExecutorAddrDiff() = default;
explicit ExecutorAddrDiff(uint64_t Value) : Value(Value) {}
uint64_t getValue() const { return Value; }
private:
int64_t Value = 0;
};
/// Represents an address in the executor process.
class ExecutorAddress {
public:
ExecutorAddress() = default;
explicit ExecutorAddress(uint64_t Addr) : Addr(Addr) {}
/// Create an ExecutorAddress from the given pointer.
/// Warning: This should only be used when JITing in-process.
template <typename T> static ExecutorAddress fromPtr(T *Value) {
return ExecutorAddress(
static_cast<uint64_t>(reinterpret_cast<uintptr_t>(Value)));
}
/// Cast this ExecutorAddress to a pointer of the given type.
/// Warning: This should only be esude when JITing in-process.
template <typename T> T toPtr() const {
static_assert(std::is_pointer<T>::value, "T must be a pointer type");
uintptr_t IntPtr = static_cast<uintptr_t>(Addr);
assert(IntPtr == Addr &&
"JITTargetAddress value out of range for uintptr_t");
return reinterpret_cast<T>(IntPtr);
}
uint64_t getValue() const { return Addr; }
void setValue(uint64_t Addr) { this->Addr = Addr; }
bool isNull() const { return Addr == 0; }
explicit operator bool() const { return Addr != 0; }
friend bool operator==(const ExecutorAddress &LHS,
const ExecutorAddress &RHS) {
return LHS.Addr == RHS.Addr;
}
friend bool operator!=(const ExecutorAddress &LHS,
const ExecutorAddress &RHS) {
return LHS.Addr != RHS.Addr;
}
friend bool operator<(const ExecutorAddress &LHS,
const ExecutorAddress &RHS) {
return LHS.Addr < RHS.Addr;
}
friend bool operator<=(const ExecutorAddress &LHS,
const ExecutorAddress &RHS) {
return LHS.Addr <= RHS.Addr;
}
friend bool operator>(const ExecutorAddress &LHS,
const ExecutorAddress &RHS) {
return LHS.Addr > RHS.Addr;
}
friend bool operator>=(const ExecutorAddress &LHS,
const ExecutorAddress &RHS) {
return LHS.Addr >= RHS.Addr;
}
ExecutorAddress &operator++() {
++Addr;
return *this;
}
ExecutorAddress &operator--() {
--Addr;
return *this;
}
ExecutorAddress operator++(int) { return ExecutorAddress(Addr++); }
ExecutorAddress operator--(int) { return ExecutorAddress(Addr++); }
ExecutorAddress &operator+=(const ExecutorAddrDiff Delta) {
Addr += Delta.getValue();
return *this;
}
ExecutorAddress &operator-=(const ExecutorAddrDiff Delta) {
Addr -= Delta.getValue();
return *this;
}
private:
uint64_t Addr = 0;
};
/// Subtracting two addresses yields an offset.
inline ExecutorAddrDiff operator-(const ExecutorAddress &LHS,
const ExecutorAddress &RHS) {
return ExecutorAddrDiff(LHS.getValue() - RHS.getValue());
}
/// Adding an offset and an address yields an address.
inline ExecutorAddress operator+(const ExecutorAddress &LHS,
const ExecutorAddrDiff &RHS) {
return ExecutorAddress(LHS.getValue() + RHS.getValue());
}
/// Adding an address and an offset yields an address.
inline ExecutorAddress operator+(const ExecutorAddrDiff &LHS,
const ExecutorAddress &RHS) {
return ExecutorAddress(LHS.getValue() + RHS.getValue());
}
/// Represents an address range in the exceutor process.
struct ExecutorAddressRange {
ExecutorAddressRange() = default;
ExecutorAddressRange(ExecutorAddress StartAddress, ExecutorAddress EndAddress)
: StartAddress(StartAddress), EndAddress(EndAddress) {}
bool empty() const { return StartAddress == EndAddress; }
ExecutorAddrDiff size() const { return EndAddress - StartAddress; }
ExecutorAddress StartAddress;
ExecutorAddress EndAddress;
};
namespace shared {
/// SPS serializatior for ExecutorAddress.
template <> class SPSSerializationTraits<SPSExecutorAddress, ExecutorAddress> {
public:
static size_t size(const ExecutorAddress &EA) {
return SPSArgList<uint64_t>::size(EA.getValue());
}
static bool serialize(SPSOutputBuffer &BOB, const ExecutorAddress &EA) {
return SPSArgList<uint64_t>::serialize(BOB, EA.getValue());
}
static bool deserialize(SPSInputBuffer &BIB, ExecutorAddress &EA) {
uint64_t Tmp;
if (!SPSArgList<uint64_t>::deserialize(BIB, Tmp))
return false;
EA = ExecutorAddress(Tmp);
return true;
}
};
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_EXECUTORADDRESS_H

View File

@ -88,13 +88,12 @@ bool objCRegistrationEnabled() {
void MachOJITDylibInitializers::runModInits() const {
for (const auto &ModInit : ModInitSections) {
assert(ModInit.size() % sizeof(uintptr_t) == 0 &&
assert(ModInit.size().getValue() % 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);
for (uintptr_t *InitPtr = jitTargetAddressToPointer<uintptr_t *>(
ModInit.StartAddress.getValue()),
*InitEnd = jitTargetAddressToPointer<uintptr_t *>(
ModInit.EndAddress.getValue());
InitPtr != InitEnd; ++InitPtr) {
auto *Initializer = reinterpret_cast<void (*)()>(*InitPtr);
Initializer();
@ -106,15 +105,15 @@ void MachOJITDylibInitializers::registerObjCSelectors() const {
assert(objCRegistrationEnabled() && "ObjC registration not enabled.");
for (const auto &ObjCSelRefs : ObjCSelRefsSections) {
assert(ObjCSelRefs.size() % sizeof(uintptr_t) == 0 &&
assert(ObjCSelRefs.size().getValue() % sizeof(uintptr_t) == 0 &&
"ObjCSelRefs section size is not a pointer multiple?");
for (JITTargetAddress SelEntryAddr = ObjCSelRefs.StartAddress;
for (auto SelEntryAddr = ObjCSelRefs.StartAddress;
SelEntryAddr != ObjCSelRefs.EndAddress;
SelEntryAddr += sizeof(uintptr_t)) {
SelEntryAddr += ExecutorAddrDiff(sizeof(uintptr_t))) {
const auto *SelName =
*jitTargetAddressToPointer<const char **>(SelEntryAddr);
*jitTargetAddressToPointer<const char **>(SelEntryAddr.getValue());
auto Sel = sel_registerName(SelName);
*jitTargetAddressToPointer<SEL *>(SelEntryAddr) = Sel;
*jitTargetAddressToPointer<SEL *>(SelEntryAddr.getValue()) = Sel;
}
}
}
@ -135,14 +134,13 @@ Error MachOJITDylibInitializers::registerObjCClasses() const {
auto ClassSelector = sel_registerName("class");
for (const auto &ObjCClassList : ObjCClassListSections) {
assert(ObjCClassList.size() % sizeof(uintptr_t) == 0 &&
assert(ObjCClassList.size().getValue() % sizeof(uintptr_t) == 0 &&
"ObjCClassList section size is not a pointer multiple?");
for (JITTargetAddress ClassPtrAddr = ObjCClassList.StartAddress;
for (auto ClassPtrAddr = ObjCClassList.StartAddress;
ClassPtrAddr != ObjCClassList.EndAddress;
ClassPtrAddr += sizeof(uintptr_t)) {
auto Cls = *jitTargetAddressToPointer<Class *>(ClassPtrAddr);
auto *ClassCompiled =
*jitTargetAddressToPointer<ObjCClassCompiled **>(ClassPtrAddr);
ClassPtrAddr += ExecutorAddrDiff(sizeof(uintptr_t))) {
auto Cls = *ClassPtrAddr.toPtr<Class *>();
auto *ClassCompiled = *ClassPtrAddr.toPtr<ObjCClassCompiled **>();
objc_msgSend(reinterpret_cast<id>(ClassCompiled->Parent), ClassSelector);
auto Registered = objc_readClassPair(Cls, ImageInfo);
@ -272,11 +270,11 @@ MachOPlatform::getDeinitializerSequence(JITDylib &JD) {
return FullDeinitSeq;
}
void MachOPlatform::registerInitInfo(
JITDylib &JD, JITTargetAddress ObjCImageInfoAddr,
shared::ExecutorAddressRange ModInits,
shared::ExecutorAddressRange ObjCSelRefs,
shared::ExecutorAddressRange ObjCClassList) {
void MachOPlatform::registerInitInfo(JITDylib &JD,
JITTargetAddress ObjCImageInfoAddr,
ExecutorAddressRange ModInits,
ExecutorAddressRange ObjCSelRefs,
ExecutorAddressRange ObjCClassList) {
std::lock_guard<std::mutex> Lock(InitSeqsMutex);
auto &InitSeq = InitSeqs[&JD];
@ -293,17 +291,18 @@ void MachOPlatform::registerInitInfo(
InitSeq.addObjCClassListSection(std::move(ObjCClassList));
}
static Expected<shared::ExecutorAddressRange>
getSectionExtent(jitlink::LinkGraph &G, StringRef SectionName) {
static Expected<ExecutorAddressRange> getSectionExtent(jitlink::LinkGraph &G,
StringRef SectionName) {
auto *Sec = G.findSectionByName(SectionName);
if (!Sec)
return shared::ExecutorAddressRange();
return 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 shared::ExecutorAddressRange{R.getStart(), R.getEnd()};
return ExecutorAddressRange(ExecutorAddress(R.getStart()),
ExecutorAddress(R.getEnd()));
}
void MachOPlatform::InitScraperPlugin::modifyPassConfig(
@ -332,7 +331,7 @@ void MachOPlatform::InitScraperPlugin::modifyPassConfig(
Config.PostFixupPasses.push_back([this, &JD = MR.getTargetJITDylib()](
jitlink::LinkGraph &G) -> Error {
shared::ExecutorAddressRange ModInits, ObjCSelRefs, ObjCClassList;
ExecutorAddressRange ModInits, ObjCSelRefs, ObjCClassList;
JITTargetAddress ObjCImageInfoAddr = 0;
if (auto *ObjCImageInfoSec =
@ -364,26 +363,28 @@ void MachOPlatform::InitScraperPlugin::modifyPassConfig(
LLVM_DEBUG({
dbgs() << "MachOPlatform: Scraped " << G.getName() << " init sections:\n";
dbgs() << " __objc_selrefs: ";
auto NumObjCSelRefs = ObjCSelRefs.size() / sizeof(uintptr_t);
auto NumObjCSelRefs = ObjCSelRefs.size().getValue() / sizeof(uintptr_t);
if (NumObjCSelRefs)
dbgs() << NumObjCSelRefs << " pointer(s) at "
<< formatv("{0:x16}", ObjCSelRefs.StartAddress) << "\n";
<< formatv("{0:x16}", ObjCSelRefs.StartAddress.getValue())
<< "\n";
else
dbgs() << "none\n";
dbgs() << " __objc_classlist: ";
auto NumObjCClasses = ObjCClassList.size() / sizeof(uintptr_t);
auto NumObjCClasses = ObjCClassList.size().getValue() / sizeof(uintptr_t);
if (NumObjCClasses)
dbgs() << NumObjCClasses << " pointer(s) at "
<< formatv("{0:x16}", ObjCClassList.StartAddress) << "\n";
<< formatv("{0:x16}", ObjCClassList.StartAddress.getValue())
<< "\n";
else
dbgs() << "none\n";
dbgs() << " __mod_init_func: ";
auto NumModInits = ModInits.size() / sizeof(uintptr_t);
auto NumModInits = ModInits.size().getValue() / sizeof(uintptr_t);
if (NumModInits)
dbgs() << NumModInits << " pointer(s) at "
<< formatv("{0:x16}", ModInits.StartAddress) << "\n";
<< formatv("{0:x16}", ModInits.StartAddress.getValue()) << "\n";
else
dbgs() << "none\n";
});