[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:
Lang Hames 2021-09-22 15:34:46 +10:00
parent 25ac0d3c73
commit a2c1cf09df
12 changed files with 416 additions and 146 deletions

View File

@ -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

View File

@ -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);

View File

@ -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;

View File

@ -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

View File

@ -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);

View File

@ -7,6 +7,7 @@ add_llvm_component_library(LLVMOrcJIT
EPCDynamicLibrarySearchGenerator.cpp
EPCDebugObjectRegistrar.cpp
EPCEHFrameRegistrar.cpp
EPCGenericDylibManager.cpp
EPCGenericJITLinkMemoryManager.cpp
EPCIndirectionUtils.cpp
ExecutionUtils.cpp

View 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

View File

@ -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 =

View File

@ -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();

View File

@ -2,6 +2,7 @@ add_llvm_component_library(LLVMOrcTargetProcess
JITLoaderGDB.cpp
OrcRTBootstrap.cpp
RegisterEHFrames.cpp
SimpleExecutorDylibManager.cpp
SimpleExecutorMemoryManager.cpp
SimpleRemoteEPCServer.cpp
TargetExecutionUtils.cpp

View File

@ -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

View File

@ -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) {