[ORC] Use raw OS handle values, ExecutorAddr for EPC dylib handles.
Updates tpctypes::DylibHandle to be an ExecutorAddr (rather than a uint64_t), and SimpleExecutorDylibManager to hold and return raw OS handle values (as ExecutorAddrs) rather than index values into a map of DynamicLibrary instances. This will allow clients to use EPCGenericDylibManager in contexts where the existing DynamicLibrary interface is too limited to be used. (e.g. to look up JIT symbols in a dylib that was loaded with RTLD_LOCAL).
This commit is contained in:
@@ -51,12 +51,13 @@ extern const char *RunAsVoidFunctionWrapperName;
|
||||
extern const char *RunAsIntFunctionWrapperName;
|
||||
|
||||
using SPSSimpleExecutorDylibManagerOpenSignature =
|
||||
shared::SPSExpected<uint64_t>(shared::SPSExecutorAddr, shared::SPSString,
|
||||
uint64_t);
|
||||
shared::SPSExpected<shared::SPSExecutorAddr>(shared::SPSExecutorAddr,
|
||||
shared::SPSString, uint64_t);
|
||||
|
||||
using SPSSimpleExecutorDylibManagerLookupSignature =
|
||||
shared::SPSExpected<shared::SPSSequence<shared::SPSExecutorAddr>>(
|
||||
shared::SPSExecutorAddr, uint64_t, shared::SPSRemoteSymbolLookupSet);
|
||||
shared::SPSExecutorAddr, shared::SPSExecutorAddr,
|
||||
shared::SPSRemoteSymbolLookupSet);
|
||||
|
||||
using SPSSimpleExecutorMemoryManagerReserveSignature =
|
||||
shared::SPSExpected<shared::SPSExecutorAddr>(shared::SPSExecutorAddr,
|
||||
|
||||
@@ -85,9 +85,9 @@ struct BufferWrite {
|
||||
};
|
||||
|
||||
/// A handle used to represent a loaded dylib in the target process.
|
||||
using DylibHandle = JITTargetAddress;
|
||||
using DylibHandle = ExecutorAddr;
|
||||
|
||||
using LookupResult = std::vector<JITTargetAddress>;
|
||||
using LookupResult = std::vector<ExecutorAddr>;
|
||||
|
||||
} // end namespace tpctypes
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
#ifndef LLVM_EXECUTIONENGINE_ORC_TARGETPROCESS_SIMPLEEXECUTORDYLIBMANAGER_H
|
||||
#define LLVM_EXECUTIONENGINE_ORC_TARGETPROCESS_SIMPLEEXECUTORDYLIBMANAGER_H
|
||||
|
||||
#include "llvm/ADT/DenseMap.h"
|
||||
#include "llvm/ADT/DenseSet.h"
|
||||
#include "llvm/ExecutionEngine/Orc/Shared/ExecutorAddress.h"
|
||||
#include "llvm/ExecutionEngine/Orc/Shared/SimpleRemoteEPCUtils.h"
|
||||
#include "llvm/ExecutionEngine/Orc/Shared/TargetProcessControlTypes.h"
|
||||
@@ -44,7 +44,7 @@ public:
|
||||
void addBootstrapSymbols(StringMap<ExecutorAddr> &M) override;
|
||||
|
||||
private:
|
||||
using DylibsMap = DenseMap<uint64_t, sys::DynamicLibrary>;
|
||||
using DylibSet = DenseSet<void *>;
|
||||
|
||||
static llvm::orc::shared::CWrapperFunctionResult
|
||||
openWrapper(const char *ArgData, size_t ArgSize);
|
||||
@@ -53,8 +53,7 @@ private:
|
||||
lookupWrapper(const char *ArgData, size_t ArgSize);
|
||||
|
||||
std::mutex M;
|
||||
uint64_t NextId = 0;
|
||||
DylibsMap Dylibs;
|
||||
DylibSet Dylibs;
|
||||
};
|
||||
|
||||
} // end namespace rt_bootstrap
|
||||
|
||||
@@ -42,6 +42,9 @@ class DynamicLibrary {
|
||||
public:
|
||||
explicit DynamicLibrary(void *data = &Invalid) : Data(data) {}
|
||||
|
||||
/// Return the OS specific handle value.
|
||||
void *getOSSpecificHandle() const { return Data; }
|
||||
|
||||
/// Returns true if the object refers to a valid library.
|
||||
bool isValid() const { return Data != &Invalid; }
|
||||
|
||||
|
||||
@@ -54,7 +54,7 @@ Error EPCDynamicLibrarySearchGenerator::tryToGenerate(
|
||||
for (auto &KV : LookupSymbols) {
|
||||
if (*ResultI)
|
||||
NewSymbols[KV.first] =
|
||||
JITEvaluatedSymbol(*ResultI, JITSymbolFlags::Exported);
|
||||
JITEvaluatedSymbol(ResultI->getValue(), JITSymbolFlags::Exported);
|
||||
++ResultI;
|
||||
}
|
||||
|
||||
|
||||
@@ -73,7 +73,7 @@ EPCGenericDylibManager::CreateWithDefaultBootstrapSymbols(
|
||||
|
||||
Expected<tpctypes::DylibHandle> EPCGenericDylibManager::open(StringRef Path,
|
||||
uint64_t Mode) {
|
||||
Expected<tpctypes::DylibHandle> H(0);
|
||||
Expected<tpctypes::DylibHandle> H((ExecutorAddr()));
|
||||
if (auto Err =
|
||||
EPC.callSPSWrapper<rt::SPSSimpleExecutorDylibManagerOpenSignature>(
|
||||
SAs.Open, H, SAs.Instance, Path, Mode))
|
||||
|
||||
@@ -80,7 +80,7 @@ SelfExecutorProcessControl::loadDylib(const char *DylibPath) {
|
||||
if (!Dylib->isValid())
|
||||
return make_error<StringError>(std::move(ErrMsg), inconvertibleErrorCode());
|
||||
DynamicLibraries.push_back(std::move(Dylib));
|
||||
return pointerToJITTargetAddress(DynamicLibraries.back().get());
|
||||
return ExecutorAddr::fromPtr(DynamicLibraries.back().get());
|
||||
}
|
||||
|
||||
Expected<std::vector<tpctypes::LookupResult>>
|
||||
@@ -88,14 +88,14 @@ SelfExecutorProcessControl::lookupSymbols(ArrayRef<LookupRequest> Request) {
|
||||
std::vector<tpctypes::LookupResult> R;
|
||||
|
||||
for (auto &Elem : Request) {
|
||||
auto *Dylib = jitTargetAddressToPointer<sys::DynamicLibrary *>(Elem.Handle);
|
||||
auto *Dylib = Elem.Handle.toPtr<sys::DynamicLibrary *>();
|
||||
assert(llvm::any_of(DynamicLibraries,
|
||||
[=](const std::unique_ptr<sys::DynamicLibrary> &DL) {
|
||||
return DL.get() == Dylib;
|
||||
}) &&
|
||||
"Invalid handle");
|
||||
|
||||
R.push_back(std::vector<JITTargetAddress>());
|
||||
R.push_back(std::vector<ExecutorAddr>());
|
||||
for (auto &KV : Elem.Symbols) {
|
||||
auto &Sym = KV.first;
|
||||
std::string Tmp((*Sym).data() + !!GlobalManglingPrefix,
|
||||
@@ -107,7 +107,7 @@ SelfExecutorProcessControl::lookupSymbols(ArrayRef<LookupRequest> Request) {
|
||||
MissingSymbols.push_back(Sym);
|
||||
return make_error<SymbolsNotFound>(SSP, std::move(MissingSymbols));
|
||||
}
|
||||
R.back().push_back(pointerToJITTargetAddress(Addr));
|
||||
R.back().push_back(ExecutorAddr::fromPtr(Addr));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -73,7 +73,7 @@ Error lookupAndRecordAddrs(
|
||||
inconvertibleErrorCode());
|
||||
|
||||
for (unsigned I = 0; I != Pairs.size(); ++I)
|
||||
Pairs[I].second->setValue(Result->front()[I]);
|
||||
*Pairs[I].second = Result->front()[I];
|
||||
|
||||
return Error::success();
|
||||
}
|
||||
|
||||
@@ -38,7 +38,7 @@ SimpleRemoteEPC::lookupSymbols(ArrayRef<LookupRequest> Request) {
|
||||
Result.push_back({});
|
||||
Result.back().reserve(R->size());
|
||||
for (auto Addr : *R)
|
||||
Result.back().push_back(Addr.getValue());
|
||||
Result.back().push_back(Addr);
|
||||
} else
|
||||
return R.takeError();
|
||||
}
|
||||
|
||||
@@ -35,24 +35,18 @@ SimpleExecutorDylibManager::open(const std::string &Path, uint64_t Mode) {
|
||||
return make_error<StringError>(std::move(ErrMsg), inconvertibleErrorCode());
|
||||
|
||||
std::lock_guard<std::mutex> Lock(M);
|
||||
Dylibs[NextId] = std::move(DL);
|
||||
return NextId++;
|
||||
auto H = ExecutorAddr::fromPtr(DL.getOSSpecificHandle());
|
||||
Dylibs.insert(DL.getOSSpecificHandle());
|
||||
return H;
|
||||
}
|
||||
|
||||
Expected<std::vector<ExecutorAddr>>
|
||||
SimpleExecutorDylibManager::lookup(tpctypes::DylibHandle H,
|
||||
const RemoteSymbolLookupSet &L) {
|
||||
std::vector<ExecutorAddr> Result;
|
||||
|
||||
std::lock_guard<std::mutex> Lock(M);
|
||||
auto I = Dylibs.find(H);
|
||||
if (I == Dylibs.end())
|
||||
return make_error<StringError>("No dylib for handle " + formatv("{0:x}", H),
|
||||
inconvertibleErrorCode());
|
||||
auto &DL = I->second;
|
||||
auto DL = sys::DynamicLibrary(H.toPtr<void *>());
|
||||
|
||||
for (const auto &E : L) {
|
||||
|
||||
if (E.Name.empty()) {
|
||||
if (E.Required)
|
||||
return make_error<StringError>("Required address for empty symbol \"\"",
|
||||
@@ -85,10 +79,10 @@ SimpleExecutorDylibManager::lookup(tpctypes::DylibHandle H,
|
||||
|
||||
Error SimpleExecutorDylibManager::shutdown() {
|
||||
|
||||
DylibsMap DM;
|
||||
DylibSet DS;
|
||||
{
|
||||
std::lock_guard<std::mutex> Lock(M);
|
||||
std::swap(DM, Dylibs);
|
||||
std::swap(DS, Dylibs);
|
||||
}
|
||||
|
||||
// There is no removal of dylibs at the moment, so nothing to do here.
|
||||
|
||||
Reference in New Issue
Block a user