[ORC] Introduce EPCGenericDylibManager / SimpleExecutorDylibManager.
EPCGenericDylibManager provides an interface for loading dylibs and looking up symbols in the executor, implemented using EPC-calls to functions in the executor. SimpleExecutorDylibManager is an executor-side service that provides the functions used by EPCGenericDylibManager. SimpleRemoteEPC is updated to use an EPCGenericDylibManager instance to implement the ExecutorProcessControl loadDylib and lookup methods. In a future commit these methods will be removed, and clients updated to use EPCGenericDylibManagers directly.
This commit is contained in:
parent
25ac0d3c73
commit
a2c1cf09df
@ -0,0 +1,67 @@
|
||||
//===- EPCGenericDylibManager.h -- Generic EPC Dylib management -*- 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
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Implements dylib loading and searching by making calls to
|
||||
// ExecutorProcessControl::callWrapper.
|
||||
//
|
||||
// This simplifies the implementaton of new ExecutorProcessControl instances,
|
||||
// as this implementation will always work (at the cost of some performance
|
||||
// overhead for the calls).
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_EXECUTIONENGINE_ORC_EPCGENERICDYLIBMANAGER_H
|
||||
#define LLVM_EXECUTIONENGINE_ORC_EPCGENERICDYLIBMANAGER_H
|
||||
|
||||
#include "llvm/ExecutionEngine/Orc/ExecutorProcessControl.h"
|
||||
#include "llvm/ExecutionEngine/Orc/Shared/SimpleRemoteEPCUtils.h"
|
||||
|
||||
namespace llvm {
|
||||
namespace orc {
|
||||
|
||||
class SymbolLookupSet;
|
||||
|
||||
class EPCGenericDylibManager {
|
||||
public:
|
||||
/// Function addresses for memory access.
|
||||
struct SymbolAddrs {
|
||||
ExecutorAddress Instance;
|
||||
ExecutorAddress Open;
|
||||
ExecutorAddress Lookup;
|
||||
};
|
||||
|
||||
/// Create an EPCGenericMemoryAccess instance from a given set of
|
||||
/// function addrs.
|
||||
static Expected<EPCGenericDylibManager>
|
||||
CreateWithDefaultBootstrapSymbols(ExecutorProcessControl &EPC);
|
||||
|
||||
/// Create an EPCGenericMemoryAccess instance from a given set of
|
||||
/// function addrs.
|
||||
EPCGenericDylibManager(ExecutorProcessControl &EPC, SymbolAddrs SAs)
|
||||
: EPC(EPC), SAs(SAs) {}
|
||||
|
||||
/// Loads the dylib with the given name.
|
||||
Expected<tpctypes::DylibHandle> open(StringRef Path, uint64_t Mode);
|
||||
|
||||
/// Looks up symbols within the given dylib.
|
||||
Expected<std::vector<ExecutorAddress>> lookup(tpctypes::DylibHandle H,
|
||||
const SymbolLookupSet &Lookup);
|
||||
|
||||
/// Looks up symbols within the given dylib.
|
||||
Expected<std::vector<ExecutorAddress>>
|
||||
lookup(tpctypes::DylibHandle H, const RemoteSymbolLookupSet &Lookup);
|
||||
|
||||
private:
|
||||
ExecutorProcessControl &EPC;
|
||||
SymbolAddrs SAs;
|
||||
};
|
||||
|
||||
} // end namespace orc
|
||||
} // end namespace llvm
|
||||
|
||||
#endif // LLVM_EXECUTIONENGINE_ORC_EPCGENERICDYLIBMANAGER_H
|
||||
@ -15,12 +15,17 @@
|
||||
|
||||
#include "llvm/ADT/StringMap.h"
|
||||
#include "llvm/ExecutionEngine/Orc/Shared/ExecutorAddress.h"
|
||||
#include "llvm/ExecutionEngine/Orc/Shared/SimpleRemoteEPCUtils.h"
|
||||
#include "llvm/ExecutionEngine/Orc/Shared/TargetProcessControlTypes.h"
|
||||
|
||||
namespace llvm {
|
||||
namespace orc {
|
||||
namespace rt {
|
||||
|
||||
extern const char *SimpleExecutorDylibManagerInstanceName;
|
||||
extern const char *SimpleExecutorDylibManagerOpenWrapperName;
|
||||
extern const char *SimpleExecutorDylibManagerLookupWrapperName;
|
||||
|
||||
extern const char *SimpleExecutorMemoryManagerInstanceName;
|
||||
extern const char *SimpleExecutorMemoryManagerReserveWrapperName;
|
||||
extern const char *SimpleExecutorMemoryManagerFinalizeWrapperName;
|
||||
@ -31,8 +36,17 @@ extern const char *MemoryWriteUInt16sWrapperName;
|
||||
extern const char *MemoryWriteUInt32sWrapperName;
|
||||
extern const char *MemoryWriteUInt64sWrapperName;
|
||||
extern const char *MemoryWriteBuffersWrapperName;
|
||||
|
||||
extern const char *RunAsMainWrapperName;
|
||||
|
||||
using SPSSimpleExecutorDylibManagerOpenSignature =
|
||||
shared::SPSExpected<uint64_t>(shared::SPSExecutorAddress, shared::SPSString,
|
||||
uint64_t);
|
||||
|
||||
using SPSSimpleExecutorDylibManagerLookupSignature =
|
||||
shared::SPSExpected<shared::SPSSequence<shared::SPSExecutorAddress>>(
|
||||
shared::SPSExecutorAddress, uint64_t, shared::SPSRemoteSymbolLookupSet);
|
||||
|
||||
using SPSSimpleExecutorMemoryManagerReserveSignature =
|
||||
shared::SPSExpected<shared::SPSExecutorAddress>(shared::SPSExecutorAddress,
|
||||
uint64_t);
|
||||
|
||||
@ -15,6 +15,8 @@
|
||||
|
||||
#include "llvm/ADT/DenseMap.h"
|
||||
#include "llvm/ADT/FunctionExtras.h"
|
||||
#include "llvm/ExecutionEngine/Orc/EPCGenericDylibManager.h"
|
||||
#include "llvm/ExecutionEngine/Orc/EPCGenericJITLinkMemoryManager.h"
|
||||
#include "llvm/ExecutionEngine/Orc/EPCGenericMemoryAccess.h"
|
||||
#include "llvm/ExecutionEngine/Orc/ExecutorProcessControl.h"
|
||||
#include "llvm/ExecutionEngine/Orc/Shared/SimpleRemoteEPCUtils.h"
|
||||
@ -113,8 +115,7 @@ private:
|
||||
std::unique_ptr<jitlink::JITLinkMemoryManager> OwnedMemMgr;
|
||||
std::unique_ptr<MemoryAccess> OwnedMemAccess;
|
||||
|
||||
ExecutorAddress LoadDylibAddr;
|
||||
ExecutorAddress LookupSymbolsAddr;
|
||||
std::unique_ptr<EPCGenericDylibManager> DylibMgr;
|
||||
ExecutorAddress RunAsMainAddr;
|
||||
|
||||
uint64_t NextSeqNo = 0;
|
||||
|
||||
@ -0,0 +1,64 @@
|
||||
//===--------------- SimpleExecutorDylibManager.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
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// A simple dynamic library management class. Allows dynamic libraries to be
|
||||
// loaded and searched.
|
||||
//
|
||||
// FIXME: The functionality in this file should be moved to the ORC runtime.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_EXECUTIONENGINE_ORC_TARGETPROCESS_SIMPLEEXECUTORDYLIBMANAGER_H
|
||||
#define LLVM_EXECUTIONENGINE_ORC_TARGETPROCESS_SIMPLEEXECUTORDYLIBMANAGER_H
|
||||
|
||||
#include "llvm/ADT/DenseMap.h"
|
||||
#include "llvm/ExecutionEngine/Orc/Shared/ExecutorAddress.h"
|
||||
#include "llvm/ExecutionEngine/Orc/Shared/SimpleRemoteEPCUtils.h"
|
||||
#include "llvm/ExecutionEngine/Orc/Shared/TargetProcessControlTypes.h"
|
||||
#include "llvm/ExecutionEngine/Orc/Shared/WrapperFunctionUtils.h"
|
||||
#include "llvm/ExecutionEngine/Orc/TargetProcess/ExecutorBootstrapService.h"
|
||||
#include "llvm/Support/DynamicLibrary.h"
|
||||
#include "llvm/Support/Error.h"
|
||||
|
||||
#include <mutex>
|
||||
|
||||
namespace llvm {
|
||||
namespace orc {
|
||||
namespace rt_bootstrap {
|
||||
|
||||
/// Simple page-based allocator.
|
||||
class SimpleExecutorDylibManager : public ExecutorBootstrapService {
|
||||
public:
|
||||
virtual ~SimpleExecutorDylibManager();
|
||||
|
||||
Expected<tpctypes::DylibHandle> open(const std::string &Path, uint64_t Mode);
|
||||
Expected<std::vector<ExecutorAddress>> lookup(tpctypes::DylibHandle H,
|
||||
const RemoteSymbolLookupSet &L);
|
||||
|
||||
Error shutdown() override;
|
||||
void addBootstrapSymbols(StringMap<ExecutorAddress> &M) override;
|
||||
|
||||
private:
|
||||
using DylibsMap = DenseMap<uint64_t, sys::DynamicLibrary>;
|
||||
|
||||
static llvm::orc::shared::detail::CWrapperFunctionResult
|
||||
openWrapper(const char *ArgData, size_t ArgSize);
|
||||
|
||||
static llvm::orc::shared::detail::CWrapperFunctionResult
|
||||
lookupWrapper(const char *ArgData, size_t ArgSize);
|
||||
|
||||
std::mutex M;
|
||||
uint64_t NextId = 0;
|
||||
DylibsMap Dylibs;
|
||||
};
|
||||
|
||||
} // end namespace rt_bootstrap
|
||||
} // end namespace orc
|
||||
} // end namespace llvm
|
||||
|
||||
#endif // LLVM_EXECUTIONENGINE_ORC_TARGETPROCESS_SIMPLEEXECUTORDYLIBMANAGER_H
|
||||
@ -20,6 +20,7 @@
|
||||
#include "llvm/ExecutionEngine/Orc/Shared/TargetProcessControlTypes.h"
|
||||
#include "llvm/ExecutionEngine/Orc/Shared/WrapperFunctionUtils.h"
|
||||
#include "llvm/ExecutionEngine/Orc/TargetProcess/ExecutorBootstrapService.h"
|
||||
#include "llvm/ExecutionEngine/Orc/TargetProcess/SimpleExecutorDylibManager.h"
|
||||
#include "llvm/Support/DynamicLibrary.h"
|
||||
#include "llvm/Support/Error.h"
|
||||
|
||||
@ -106,6 +107,8 @@ public:
|
||||
|
||||
// If transport creation succeeds then start up services.
|
||||
Server->Services = std::move(S.services());
|
||||
Server->Services.push_back(
|
||||
std::make_unique<rt_bootstrap::SimpleExecutorDylibManager>());
|
||||
for (auto &Service : Server->Services)
|
||||
Service->addBootstrapSymbols(S.bootstrapSymbols());
|
||||
|
||||
@ -141,18 +144,6 @@ private:
|
||||
void handleCallWrapper(uint64_t RemoteSeqNo, ExecutorAddress TagAddr,
|
||||
SimpleRemoteEPCArgBytesVector ArgBytes);
|
||||
|
||||
static shared::detail::CWrapperFunctionResult
|
||||
loadDylibWrapper(const char *ArgData, size_t ArgSize);
|
||||
|
||||
static shared::detail::CWrapperFunctionResult
|
||||
lookupSymbolsWrapper(const char *ArgData, size_t ArgSize);
|
||||
|
||||
Expected<tpctypes::DylibHandle> loadDylib(const std::string &Path,
|
||||
uint64_t Mode);
|
||||
|
||||
Expected<std::vector<std::vector<ExecutorAddress>>>
|
||||
lookupSymbols(const std::vector<RemoteSymbolLookup> &L);
|
||||
|
||||
shared::WrapperFunctionResult
|
||||
doJITDispatch(const void *FnTag, const char *ArgData, size_t ArgSize);
|
||||
|
||||
|
||||
@ -7,6 +7,7 @@ add_llvm_component_library(LLVMOrcJIT
|
||||
EPCDynamicLibrarySearchGenerator.cpp
|
||||
EPCDebugObjectRegistrar.cpp
|
||||
EPCEHFrameRegistrar.cpp
|
||||
EPCGenericDylibManager.cpp
|
||||
EPCGenericJITLinkMemoryManager.cpp
|
||||
EPCIndirectionUtils.cpp
|
||||
ExecutionUtils.cpp
|
||||
|
||||
109
llvm/lib/ExecutionEngine/Orc/EPCGenericDylibManager.cpp
Normal file
109
llvm/lib/ExecutionEngine/Orc/EPCGenericDylibManager.cpp
Normal file
@ -0,0 +1,109 @@
|
||||
//===------- EPCGenericDylibManager.cpp -- Dylib management via EPC -------===//
|
||||
//
|
||||
// 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
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "llvm/ExecutionEngine/Orc/EPCGenericDylibManager.h"
|
||||
|
||||
#include "llvm/ExecutionEngine/Orc/Core.h"
|
||||
#include "llvm/ExecutionEngine/Orc/Shared/OrcRTBridge.h"
|
||||
#include "llvm/ExecutionEngine/Orc/Shared/SimpleRemoteEPCUtils.h"
|
||||
|
||||
namespace llvm {
|
||||
namespace orc {
|
||||
namespace shared {
|
||||
|
||||
template <>
|
||||
class SPSSerializationTraits<SPSRemoteSymbolLookupSetElement,
|
||||
SymbolLookupSet::value_type> {
|
||||
public:
|
||||
static size_t size(const SymbolLookupSet::value_type &V) {
|
||||
return SPSArgList<SPSString, bool>::size(
|
||||
*V.first, V.second == SymbolLookupFlags::RequiredSymbol);
|
||||
}
|
||||
|
||||
static bool serialize(SPSOutputBuffer &OB,
|
||||
const SymbolLookupSet::value_type &V) {
|
||||
return SPSArgList<SPSString, bool>::serialize(
|
||||
OB, *V.first, V.second == SymbolLookupFlags::RequiredSymbol);
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
class TrivialSPSSequenceSerialization<SPSRemoteSymbolLookupSetElement,
|
||||
SymbolLookupSet> {
|
||||
public:
|
||||
static constexpr bool available = true;
|
||||
};
|
||||
|
||||
template <>
|
||||
class SPSSerializationTraits<SPSRemoteSymbolLookup,
|
||||
ExecutorProcessControl::LookupRequest> {
|
||||
using MemberSerialization =
|
||||
SPSArgList<SPSExecutorAddress, SPSRemoteSymbolLookupSet>;
|
||||
|
||||
public:
|
||||
static size_t size(const ExecutorProcessControl::LookupRequest &LR) {
|
||||
return MemberSerialization::size(ExecutorAddress(LR.Handle), LR.Symbols);
|
||||
}
|
||||
|
||||
static bool serialize(SPSOutputBuffer &OB,
|
||||
const ExecutorProcessControl::LookupRequest &LR) {
|
||||
return MemberSerialization::serialize(OB, ExecutorAddress(LR.Handle),
|
||||
LR.Symbols);
|
||||
}
|
||||
};
|
||||
|
||||
} // end namespace shared
|
||||
|
||||
Expected<EPCGenericDylibManager>
|
||||
EPCGenericDylibManager::CreateWithDefaultBootstrapSymbols(
|
||||
ExecutorProcessControl &EPC) {
|
||||
SymbolAddrs SAs;
|
||||
if (auto Err = EPC.getBootstrapSymbols(
|
||||
{{SAs.Instance, rt::SimpleExecutorDylibManagerInstanceName},
|
||||
{SAs.Open, rt::SimpleExecutorDylibManagerOpenWrapperName},
|
||||
{SAs.Lookup, rt::SimpleExecutorDylibManagerLookupWrapperName}}))
|
||||
return std::move(Err);
|
||||
return EPCGenericDylibManager(EPC, std::move(SAs));
|
||||
}
|
||||
|
||||
Expected<tpctypes::DylibHandle> EPCGenericDylibManager::open(StringRef Path,
|
||||
uint64_t Mode) {
|
||||
Expected<tpctypes::DylibHandle> H(0);
|
||||
if (auto Err =
|
||||
EPC.callSPSWrapper<rt::SPSSimpleExecutorDylibManagerOpenSignature>(
|
||||
SAs.Open.getValue(), H, SAs.Instance, Path, Mode))
|
||||
return std::move(Err);
|
||||
return H;
|
||||
}
|
||||
|
||||
Expected<std::vector<ExecutorAddress>>
|
||||
EPCGenericDylibManager::lookup(tpctypes::DylibHandle H,
|
||||
const SymbolLookupSet &Lookup) {
|
||||
Expected<std::vector<ExecutorAddress>> Result(
|
||||
(std::vector<ExecutorAddress>()));
|
||||
if (auto Err =
|
||||
EPC.callSPSWrapper<rt::SPSSimpleExecutorDylibManagerLookupSignature>(
|
||||
SAs.Lookup.getValue(), Result, SAs.Instance, H, Lookup))
|
||||
return std::move(Err);
|
||||
return Result;
|
||||
}
|
||||
|
||||
Expected<std::vector<ExecutorAddress>>
|
||||
EPCGenericDylibManager::lookup(tpctypes::DylibHandle H,
|
||||
const RemoteSymbolLookupSet &Lookup) {
|
||||
Expected<std::vector<ExecutorAddress>> Result(
|
||||
(std::vector<ExecutorAddress>()));
|
||||
if (auto Err =
|
||||
EPC.callSPSWrapper<rt::SPSSimpleExecutorDylibManagerLookupSignature>(
|
||||
SAs.Lookup.getValue(), Result, SAs.Instance, H, Lookup))
|
||||
return std::move(Err);
|
||||
return Result;
|
||||
}
|
||||
|
||||
} // end namespace orc
|
||||
} // end namespace llvm
|
||||
@ -12,6 +12,12 @@ namespace llvm {
|
||||
namespace orc {
|
||||
namespace rt {
|
||||
|
||||
const char *SimpleExecutorDylibManagerInstanceName =
|
||||
"__llvm_orc_SimpleExecutorDylibManager_Instance";
|
||||
const char *SimpleExecutorDylibManagerOpenWrapperName =
|
||||
"__llvm_orc_SimpleExecutorDylibManager_open_wrapper";
|
||||
const char *SimpleExecutorDylibManagerLookupWrapperName =
|
||||
"__llvm_orc_SimpleExecutorDylibManager_lookup_wrapper";
|
||||
const char *SimpleExecutorMemoryManagerInstanceName =
|
||||
"__llvm_orc_SimpleExecutorMemoryManager_Instance";
|
||||
const char *SimpleExecutorMemoryManagerReserveWrapperName =
|
||||
|
||||
@ -16,50 +16,6 @@
|
||||
|
||||
namespace llvm {
|
||||
namespace orc {
|
||||
namespace shared {
|
||||
|
||||
template <>
|
||||
class SPSSerializationTraits<SPSRemoteSymbolLookupSetElement,
|
||||
SymbolLookupSet::value_type> {
|
||||
public:
|
||||
static size_t size(const SymbolLookupSet::value_type &V) {
|
||||
return SPSArgList<SPSString, bool>::size(
|
||||
*V.first, V.second == SymbolLookupFlags::RequiredSymbol);
|
||||
}
|
||||
|
||||
static bool serialize(SPSOutputBuffer &OB,
|
||||
const SymbolLookupSet::value_type &V) {
|
||||
return SPSArgList<SPSString, bool>::serialize(
|
||||
OB, *V.first, V.second == SymbolLookupFlags::RequiredSymbol);
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
class TrivialSPSSequenceSerialization<SPSRemoteSymbolLookupSetElement,
|
||||
SymbolLookupSet> {
|
||||
public:
|
||||
static constexpr bool available = true;
|
||||
};
|
||||
|
||||
template <>
|
||||
class SPSSerializationTraits<SPSRemoteSymbolLookup,
|
||||
ExecutorProcessControl::LookupRequest> {
|
||||
using MemberSerialization =
|
||||
SPSArgList<SPSExecutorAddress, SPSRemoteSymbolLookupSet>;
|
||||
|
||||
public:
|
||||
static size_t size(const ExecutorProcessControl::LookupRequest &LR) {
|
||||
return MemberSerialization::size(ExecutorAddress(LR.Handle), LR.Symbols);
|
||||
}
|
||||
|
||||
static bool serialize(SPSOutputBuffer &OB,
|
||||
const ExecutorProcessControl::LookupRequest &LR) {
|
||||
return MemberSerialization::serialize(OB, ExecutorAddress(LR.Handle),
|
||||
LR.Symbols);
|
||||
}
|
||||
};
|
||||
|
||||
} // end namespace shared
|
||||
|
||||
SimpleRemoteEPC::~SimpleRemoteEPC() {
|
||||
assert(Disconnected && "Destroyed without disconnection");
|
||||
@ -67,24 +23,23 @@ SimpleRemoteEPC::~SimpleRemoteEPC() {
|
||||
|
||||
Expected<tpctypes::DylibHandle>
|
||||
SimpleRemoteEPC::loadDylib(const char *DylibPath) {
|
||||
Expected<tpctypes::DylibHandle> H((tpctypes::DylibHandle()));
|
||||
if (auto Err = callSPSWrapper<shared::SPSLoadDylibSignature>(
|
||||
LoadDylibAddr.getValue(), H, JDI.JITDispatchContextAddress,
|
||||
StringRef(DylibPath), (uint64_t)0))
|
||||
return std::move(Err);
|
||||
return H;
|
||||
return DylibMgr->open(DylibPath, 0);
|
||||
}
|
||||
|
||||
Expected<std::vector<tpctypes::LookupResult>>
|
||||
SimpleRemoteEPC::lookupSymbols(ArrayRef<LookupRequest> Request) {
|
||||
Expected<std::vector<tpctypes::LookupResult>> R(
|
||||
(std::vector<tpctypes::LookupResult>()));
|
||||
std::vector<tpctypes::LookupResult> Result;
|
||||
|
||||
if (auto Err = callSPSWrapper<shared::SPSLookupSymbolsSignature>(
|
||||
LookupSymbolsAddr.getValue(), R, JDI.JITDispatchContextAddress,
|
||||
Request))
|
||||
return std::move(Err);
|
||||
return R;
|
||||
for (auto &Element : Request) {
|
||||
if (auto R = DylibMgr->lookup(Element.Handle, Element.Symbols)) {
|
||||
Result.push_back({});
|
||||
Result.back().reserve(R->size());
|
||||
for (auto Addr : *R)
|
||||
Result.back().push_back(Addr.getValue());
|
||||
} else
|
||||
return R.takeError();
|
||||
}
|
||||
return std::move(Result);
|
||||
}
|
||||
|
||||
Expected<int32_t> SimpleRemoteEPC::runAsMain(JITTargetAddress MainFnAddr,
|
||||
@ -253,11 +208,15 @@ Error SimpleRemoteEPC::setup(std::unique_ptr<SimpleRemoteEPCTransport> T,
|
||||
if (auto Err = getBootstrapSymbols(
|
||||
{{JDI.JITDispatchContextAddress, ExecutorSessionObjectName},
|
||||
{JDI.JITDispatchFunctionAddress, DispatchFnName},
|
||||
{LoadDylibAddr, "__llvm_orc_load_dylib"},
|
||||
{LookupSymbolsAddr, "__llvm_orc_lookup_symbols"},
|
||||
{RunAsMainAddr, rt::RunAsMainWrapperName}}))
|
||||
return Err;
|
||||
|
||||
if (auto DM =
|
||||
EPCGenericDylibManager::CreateWithDefaultBootstrapSymbols(*this))
|
||||
DylibMgr = std::make_unique<EPCGenericDylibManager>(std::move(*DM));
|
||||
else
|
||||
return DM.takeError();
|
||||
|
||||
if (auto MemMgr = createMemoryManager()) {
|
||||
OwnedMemMgr = std::move(*MemMgr);
|
||||
this->MemMgr = OwnedMemMgr.get();
|
||||
|
||||
@ -2,6 +2,7 @@ add_llvm_component_library(LLVMOrcTargetProcess
|
||||
JITLoaderGDB.cpp
|
||||
OrcRTBootstrap.cpp
|
||||
RegisterEHFrames.cpp
|
||||
SimpleExecutorDylibManager.cpp
|
||||
SimpleExecutorMemoryManager.cpp
|
||||
SimpleRemoteEPCServer.cpp
|
||||
TargetExecutionUtils.cpp
|
||||
|
||||
@ -0,0 +1,130 @@
|
||||
//===--- SimpleExecutorDylibManager.cpp - Executor-side dylib management --===//
|
||||
//
|
||||
// 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
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "llvm/ExecutionEngine/Orc/TargetProcess/SimpleExecutorDylibManager.h"
|
||||
|
||||
#include "llvm/ExecutionEngine/Orc/Shared/OrcRTBridge.h"
|
||||
#include "llvm/Support/FormatVariadic.h"
|
||||
|
||||
#define DEBUG_TYPE "orc"
|
||||
|
||||
namespace llvm {
|
||||
namespace orc {
|
||||
namespace rt_bootstrap {
|
||||
|
||||
SimpleExecutorDylibManager::~SimpleExecutorDylibManager() {
|
||||
assert(Dylibs.empty() && "shutdown not called?");
|
||||
}
|
||||
|
||||
Expected<tpctypes::DylibHandle>
|
||||
SimpleExecutorDylibManager::open(const std::string &Path, uint64_t Mode) {
|
||||
if (Mode != 0)
|
||||
return make_error<StringError>("open: non-zero mode bits not yet supported",
|
||||
inconvertibleErrorCode());
|
||||
|
||||
const char *PathCStr = Path.empty() ? nullptr : Path.c_str();
|
||||
std::string ErrMsg;
|
||||
|
||||
auto DL = sys::DynamicLibrary::getPermanentLibrary(PathCStr, &ErrMsg);
|
||||
if (!DL.isValid())
|
||||
return make_error<StringError>(std::move(ErrMsg), inconvertibleErrorCode());
|
||||
|
||||
std::lock_guard<std::mutex> Lock(M);
|
||||
Dylibs[NextId] = std::move(DL);
|
||||
return NextId++;
|
||||
}
|
||||
|
||||
Expected<std::vector<ExecutorAddress>>
|
||||
SimpleExecutorDylibManager::lookup(tpctypes::DylibHandle H,
|
||||
const RemoteSymbolLookupSet &L) {
|
||||
std::vector<ExecutorAddress> 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;
|
||||
|
||||
for (const auto &E : L) {
|
||||
|
||||
if (E.Name.empty()) {
|
||||
if (E.Required)
|
||||
return make_error<StringError>("Required address for empty symbol \"\"",
|
||||
inconvertibleErrorCode());
|
||||
else
|
||||
Result.push_back(ExecutorAddress());
|
||||
} else {
|
||||
|
||||
const char *DemangledSymName = E.Name.c_str();
|
||||
#ifdef __APPLE__
|
||||
if (E.Name.front() != '_')
|
||||
return make_error<StringError>(Twine("MachO symbol \"") + E.Name +
|
||||
"\" missing leading '_'",
|
||||
inconvertibleErrorCode());
|
||||
++DemangledSymName;
|
||||
#endif
|
||||
|
||||
void *Addr = DL.getAddressOfSymbol(DemangledSymName);
|
||||
if (!Addr && E.Required)
|
||||
return make_error<StringError>(Twine("Missing definition for ") +
|
||||
DemangledSymName,
|
||||
inconvertibleErrorCode());
|
||||
|
||||
Result.push_back(ExecutorAddress::fromPtr(Addr));
|
||||
}
|
||||
}
|
||||
|
||||
return Result;
|
||||
}
|
||||
|
||||
Error SimpleExecutorDylibManager::shutdown() {
|
||||
|
||||
DylibsMap DM;
|
||||
{
|
||||
std::lock_guard<std::mutex> Lock(M);
|
||||
std::swap(DM, Dylibs);
|
||||
}
|
||||
|
||||
// There is no removal of dylibs at the moment, so nothing to do here.
|
||||
return Error::success();
|
||||
}
|
||||
|
||||
void SimpleExecutorDylibManager::addBootstrapSymbols(
|
||||
StringMap<ExecutorAddress> &M) {
|
||||
M[rt::SimpleExecutorDylibManagerInstanceName] =
|
||||
ExecutorAddress::fromPtr(this);
|
||||
M[rt::SimpleExecutorDylibManagerOpenWrapperName] =
|
||||
ExecutorAddress::fromPtr(&openWrapper);
|
||||
M[rt::SimpleExecutorDylibManagerLookupWrapperName] =
|
||||
ExecutorAddress::fromPtr(&lookupWrapper);
|
||||
}
|
||||
|
||||
llvm::orc::shared::detail::CWrapperFunctionResult
|
||||
SimpleExecutorDylibManager::openWrapper(const char *ArgData, size_t ArgSize) {
|
||||
return shared::
|
||||
WrapperFunction<rt::SPSSimpleExecutorDylibManagerOpenSignature>::handle(
|
||||
ArgData, ArgSize,
|
||||
shared::makeMethodWrapperHandler(
|
||||
&SimpleExecutorDylibManager::open))
|
||||
.release();
|
||||
}
|
||||
|
||||
llvm::orc::shared::detail::CWrapperFunctionResult
|
||||
SimpleExecutorDylibManager::lookupWrapper(const char *ArgData, size_t ArgSize) {
|
||||
return shared::
|
||||
WrapperFunction<rt::SPSSimpleExecutorDylibManagerLookupSignature>::handle(
|
||||
ArgData, ArgSize,
|
||||
shared::makeMethodWrapperHandler(
|
||||
&SimpleExecutorDylibManager::lookup))
|
||||
.release();
|
||||
}
|
||||
|
||||
} // namespace rt_bootstrap
|
||||
} // end namespace orc
|
||||
} // end namespace llvm
|
||||
@ -54,9 +54,6 @@ void SimpleRemoteEPCServer::ThreadDispatcher::shutdown() {
|
||||
StringMap<ExecutorAddress> SimpleRemoteEPCServer::defaultBootstrapSymbols() {
|
||||
StringMap<ExecutorAddress> DBS;
|
||||
rt_bootstrap::addTo(DBS);
|
||||
DBS["__llvm_orc_load_dylib"] = ExecutorAddress::fromPtr(&loadDylibWrapper);
|
||||
DBS["__llvm_orc_lookup_symbols"] =
|
||||
ExecutorAddress::fromPtr(&lookupSymbolsWrapper);
|
||||
return DBS;
|
||||
}
|
||||
|
||||
@ -199,76 +196,6 @@ void SimpleRemoteEPCServer::handleCallWrapper(
|
||||
});
|
||||
}
|
||||
|
||||
shared::detail::CWrapperFunctionResult
|
||||
SimpleRemoteEPCServer::loadDylibWrapper(const char *ArgData, size_t ArgSize) {
|
||||
return shared::WrapperFunction<shared::SPSLoadDylibSignature>::handle(
|
||||
ArgData, ArgSize,
|
||||
[](ExecutorAddress ExecutorSessionObj, std::string Path,
|
||||
uint64_t Flags) -> Expected<uint64_t> {
|
||||
return ExecutorSessionObj.toPtr<SimpleRemoteEPCServer *>()
|
||||
->loadDylib(Path, Flags);
|
||||
})
|
||||
.release();
|
||||
}
|
||||
|
||||
shared::detail::CWrapperFunctionResult
|
||||
SimpleRemoteEPCServer::lookupSymbolsWrapper(const char *ArgData,
|
||||
size_t ArgSize) {
|
||||
return shared::WrapperFunction<shared::SPSLookupSymbolsSignature>::handle(
|
||||
ArgData, ArgSize,
|
||||
[](ExecutorAddress ExecutorSessionObj,
|
||||
std::vector<RemoteSymbolLookup> Lookup) {
|
||||
return ExecutorSessionObj.toPtr<SimpleRemoteEPCServer *>()
|
||||
->lookupSymbols(Lookup);
|
||||
})
|
||||
.release();
|
||||
}
|
||||
|
||||
Expected<tpctypes::DylibHandle>
|
||||
SimpleRemoteEPCServer::loadDylib(const std::string &Path, uint64_t Mode) {
|
||||
std::string ErrMsg;
|
||||
const char *P = Path.empty() ? nullptr : Path.c_str();
|
||||
auto DL = sys::DynamicLibrary::getPermanentLibrary(P, &ErrMsg);
|
||||
if (!DL.isValid())
|
||||
return make_error<StringError>(std::move(ErrMsg), inconvertibleErrorCode());
|
||||
std::lock_guard<std::mutex> Lock(ServerStateMutex);
|
||||
uint64_t Id = Dylibs.size();
|
||||
Dylibs.push_back(std::move(DL));
|
||||
return Id;
|
||||
}
|
||||
|
||||
Expected<std::vector<std::vector<ExecutorAddress>>>
|
||||
SimpleRemoteEPCServer::lookupSymbols(const std::vector<RemoteSymbolLookup> &L) {
|
||||
std::vector<std::vector<ExecutorAddress>> Result;
|
||||
|
||||
for (const auto &E : L) {
|
||||
if (E.H >= Dylibs.size())
|
||||
return make_error<StringError>("Unrecognized handle",
|
||||
inconvertibleErrorCode());
|
||||
auto &DL = Dylibs[E.H];
|
||||
Result.push_back({});
|
||||
|
||||
for (const auto &Sym : E.Symbols) {
|
||||
|
||||
const char *DemangledSymName = Sym.Name.c_str();
|
||||
#ifdef __APPLE__
|
||||
if (*DemangledSymName == '_')
|
||||
++DemangledSymName;
|
||||
#endif
|
||||
|
||||
void *Addr = DL.getAddressOfSymbol(DemangledSymName);
|
||||
if (!Addr && Sym.Required)
|
||||
return make_error<StringError>(Twine("Missing definition for ") +
|
||||
DemangledSymName,
|
||||
inconvertibleErrorCode());
|
||||
|
||||
Result.back().push_back(ExecutorAddress::fromPtr(Addr));
|
||||
}
|
||||
}
|
||||
|
||||
return std::move(Result);
|
||||
}
|
||||
|
||||
shared::WrapperFunctionResult
|
||||
SimpleRemoteEPCServer::doJITDispatch(const void *FnTag, const char *ArgData,
|
||||
size_t ArgSize) {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user