Skip to content

Commit a2c1cf0

Browse files
committed
[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.
1 parent 25ac0d3 commit a2c1cf0

File tree

12 files changed

+417
-147
lines changed

12 files changed

+417
-147
lines changed
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
//===- EPCGenericDylibManager.h -- Generic EPC Dylib management -*- C++ -*-===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
//
9+
// Implements dylib loading and searching by making calls to
10+
// ExecutorProcessControl::callWrapper.
11+
//
12+
// This simplifies the implementaton of new ExecutorProcessControl instances,
13+
// as this implementation will always work (at the cost of some performance
14+
// overhead for the calls).
15+
//
16+
//===----------------------------------------------------------------------===//
17+
18+
#ifndef LLVM_EXECUTIONENGINE_ORC_EPCGENERICDYLIBMANAGER_H
19+
#define LLVM_EXECUTIONENGINE_ORC_EPCGENERICDYLIBMANAGER_H
20+
21+
#include "llvm/ExecutionEngine/Orc/ExecutorProcessControl.h"
22+
#include "llvm/ExecutionEngine/Orc/Shared/SimpleRemoteEPCUtils.h"
23+
24+
namespace llvm {
25+
namespace orc {
26+
27+
class SymbolLookupSet;
28+
29+
class EPCGenericDylibManager {
30+
public:
31+
/// Function addresses for memory access.
32+
struct SymbolAddrs {
33+
ExecutorAddress Instance;
34+
ExecutorAddress Open;
35+
ExecutorAddress Lookup;
36+
};
37+
38+
/// Create an EPCGenericMemoryAccess instance from a given set of
39+
/// function addrs.
40+
static Expected<EPCGenericDylibManager>
41+
CreateWithDefaultBootstrapSymbols(ExecutorProcessControl &EPC);
42+
43+
/// Create an EPCGenericMemoryAccess instance from a given set of
44+
/// function addrs.
45+
EPCGenericDylibManager(ExecutorProcessControl &EPC, SymbolAddrs SAs)
46+
: EPC(EPC), SAs(SAs) {}
47+
48+
/// Loads the dylib with the given name.
49+
Expected<tpctypes::DylibHandle> open(StringRef Path, uint64_t Mode);
50+
51+
/// Looks up symbols within the given dylib.
52+
Expected<std::vector<ExecutorAddress>> lookup(tpctypes::DylibHandle H,
53+
const SymbolLookupSet &Lookup);
54+
55+
/// Looks up symbols within the given dylib.
56+
Expected<std::vector<ExecutorAddress>>
57+
lookup(tpctypes::DylibHandle H, const RemoteSymbolLookupSet &Lookup);
58+
59+
private:
60+
ExecutorProcessControl &EPC;
61+
SymbolAddrs SAs;
62+
};
63+
64+
} // end namespace orc
65+
} // end namespace llvm
66+
67+
#endif // LLVM_EXECUTIONENGINE_ORC_EPCGENERICDYLIBMANAGER_H

llvm/include/llvm/ExecutionEngine/Orc/Shared/OrcRTBridge.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,17 @@
1515

1616
#include "llvm/ADT/StringMap.h"
1717
#include "llvm/ExecutionEngine/Orc/Shared/ExecutorAddress.h"
18+
#include "llvm/ExecutionEngine/Orc/Shared/SimpleRemoteEPCUtils.h"
1819
#include "llvm/ExecutionEngine/Orc/Shared/TargetProcessControlTypes.h"
1920

2021
namespace llvm {
2122
namespace orc {
2223
namespace rt {
2324

25+
extern const char *SimpleExecutorDylibManagerInstanceName;
26+
extern const char *SimpleExecutorDylibManagerOpenWrapperName;
27+
extern const char *SimpleExecutorDylibManagerLookupWrapperName;
28+
2429
extern const char *SimpleExecutorMemoryManagerInstanceName;
2530
extern const char *SimpleExecutorMemoryManagerReserveWrapperName;
2631
extern const char *SimpleExecutorMemoryManagerFinalizeWrapperName;
@@ -31,8 +36,17 @@ extern const char *MemoryWriteUInt16sWrapperName;
3136
extern const char *MemoryWriteUInt32sWrapperName;
3237
extern const char *MemoryWriteUInt64sWrapperName;
3338
extern const char *MemoryWriteBuffersWrapperName;
39+
3440
extern const char *RunAsMainWrapperName;
3541

42+
using SPSSimpleExecutorDylibManagerOpenSignature =
43+
shared::SPSExpected<uint64_t>(shared::SPSExecutorAddress, shared::SPSString,
44+
uint64_t);
45+
46+
using SPSSimpleExecutorDylibManagerLookupSignature =
47+
shared::SPSExpected<shared::SPSSequence<shared::SPSExecutorAddress>>(
48+
shared::SPSExecutorAddress, uint64_t, shared::SPSRemoteSymbolLookupSet);
49+
3650
using SPSSimpleExecutorMemoryManagerReserveSignature =
3751
shared::SPSExpected<shared::SPSExecutorAddress>(shared::SPSExecutorAddress,
3852
uint64_t);

llvm/include/llvm/ExecutionEngine/Orc/SimpleRemoteEPC.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@
1515

1616
#include "llvm/ADT/DenseMap.h"
1717
#include "llvm/ADT/FunctionExtras.h"
18+
#include "llvm/ExecutionEngine/Orc/EPCGenericDylibManager.h"
19+
#include "llvm/ExecutionEngine/Orc/EPCGenericJITLinkMemoryManager.h"
1820
#include "llvm/ExecutionEngine/Orc/EPCGenericMemoryAccess.h"
1921
#include "llvm/ExecutionEngine/Orc/ExecutorProcessControl.h"
2022
#include "llvm/ExecutionEngine/Orc/Shared/SimpleRemoteEPCUtils.h"
@@ -113,8 +115,7 @@ class SimpleRemoteEPC : public ExecutorProcessControl,
113115
std::unique_ptr<jitlink::JITLinkMemoryManager> OwnedMemMgr;
114116
std::unique_ptr<MemoryAccess> OwnedMemAccess;
115117

116-
ExecutorAddress LoadDylibAddr;
117-
ExecutorAddress LookupSymbolsAddr;
118+
std::unique_ptr<EPCGenericDylibManager> DylibMgr;
118119
ExecutorAddress RunAsMainAddr;
119120

120121
uint64_t NextSeqNo = 0;
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
//===--------------- SimpleExecutorDylibManager.h ---------------*- C++ -*-===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
//
9+
// A simple dynamic library management class. Allows dynamic libraries to be
10+
// loaded and searched.
11+
//
12+
// FIXME: The functionality in this file should be moved to the ORC runtime.
13+
//
14+
//===----------------------------------------------------------------------===//
15+
16+
#ifndef LLVM_EXECUTIONENGINE_ORC_TARGETPROCESS_SIMPLEEXECUTORDYLIBMANAGER_H
17+
#define LLVM_EXECUTIONENGINE_ORC_TARGETPROCESS_SIMPLEEXECUTORDYLIBMANAGER_H
18+
19+
#include "llvm/ADT/DenseMap.h"
20+
#include "llvm/ExecutionEngine/Orc/Shared/ExecutorAddress.h"
21+
#include "llvm/ExecutionEngine/Orc/Shared/SimpleRemoteEPCUtils.h"
22+
#include "llvm/ExecutionEngine/Orc/Shared/TargetProcessControlTypes.h"
23+
#include "llvm/ExecutionEngine/Orc/Shared/WrapperFunctionUtils.h"
24+
#include "llvm/ExecutionEngine/Orc/TargetProcess/ExecutorBootstrapService.h"
25+
#include "llvm/Support/DynamicLibrary.h"
26+
#include "llvm/Support/Error.h"
27+
28+
#include <mutex>
29+
30+
namespace llvm {
31+
namespace orc {
32+
namespace rt_bootstrap {
33+
34+
/// Simple page-based allocator.
35+
class SimpleExecutorDylibManager : public ExecutorBootstrapService {
36+
public:
37+
virtual ~SimpleExecutorDylibManager();
38+
39+
Expected<tpctypes::DylibHandle> open(const std::string &Path, uint64_t Mode);
40+
Expected<std::vector<ExecutorAddress>> lookup(tpctypes::DylibHandle H,
41+
const RemoteSymbolLookupSet &L);
42+
43+
Error shutdown() override;
44+
void addBootstrapSymbols(StringMap<ExecutorAddress> &M) override;
45+
46+
private:
47+
using DylibsMap = DenseMap<uint64_t, sys::DynamicLibrary>;
48+
49+
static llvm::orc::shared::detail::CWrapperFunctionResult
50+
openWrapper(const char *ArgData, size_t ArgSize);
51+
52+
static llvm::orc::shared::detail::CWrapperFunctionResult
53+
lookupWrapper(const char *ArgData, size_t ArgSize);
54+
55+
std::mutex M;
56+
uint64_t NextId = 0;
57+
DylibsMap Dylibs;
58+
};
59+
60+
} // end namespace rt_bootstrap
61+
} // end namespace orc
62+
} // end namespace llvm
63+
64+
#endif // LLVM_EXECUTIONENGINE_ORC_TARGETPROCESS_SIMPLEEXECUTORDYLIBMANAGER_H

llvm/include/llvm/ExecutionEngine/Orc/TargetProcess/SimpleRemoteEPCServer.h

Lines changed: 3 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
#include "llvm/ExecutionEngine/Orc/Shared/TargetProcessControlTypes.h"
2121
#include "llvm/ExecutionEngine/Orc/Shared/WrapperFunctionUtils.h"
2222
#include "llvm/ExecutionEngine/Orc/TargetProcess/ExecutorBootstrapService.h"
23+
#include "llvm/ExecutionEngine/Orc/TargetProcess/SimpleExecutorDylibManager.h"
2324
#include "llvm/Support/DynamicLibrary.h"
2425
#include "llvm/Support/Error.h"
2526

@@ -106,6 +107,8 @@ class SimpleRemoteEPCServer : public SimpleRemoteEPCTransportClient {
106107

107108
// If transport creation succeeds then start up services.
108109
Server->Services = std::move(S.services());
110+
Server->Services.push_back(
111+
std::make_unique<rt_bootstrap::SimpleExecutorDylibManager>());
109112
for (auto &Service : Server->Services)
110113
Service->addBootstrapSymbols(S.bootstrapSymbols());
111114

@@ -141,18 +144,6 @@ class SimpleRemoteEPCServer : public SimpleRemoteEPCTransportClient {
141144
void handleCallWrapper(uint64_t RemoteSeqNo, ExecutorAddress TagAddr,
142145
SimpleRemoteEPCArgBytesVector ArgBytes);
143146

144-
static shared::detail::CWrapperFunctionResult
145-
loadDylibWrapper(const char *ArgData, size_t ArgSize);
146-
147-
static shared::detail::CWrapperFunctionResult
148-
lookupSymbolsWrapper(const char *ArgData, size_t ArgSize);
149-
150-
Expected<tpctypes::DylibHandle> loadDylib(const std::string &Path,
151-
uint64_t Mode);
152-
153-
Expected<std::vector<std::vector<ExecutorAddress>>>
154-
lookupSymbols(const std::vector<RemoteSymbolLookup> &L);
155-
156147
shared::WrapperFunctionResult
157148
doJITDispatch(const void *FnTag, const char *ArgData, size_t ArgSize);
158149

llvm/lib/ExecutionEngine/Orc/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ add_llvm_component_library(LLVMOrcJIT
77
EPCDynamicLibrarySearchGenerator.cpp
88
EPCDebugObjectRegistrar.cpp
99
EPCEHFrameRegistrar.cpp
10+
EPCGenericDylibManager.cpp
1011
EPCGenericJITLinkMemoryManager.cpp
1112
EPCIndirectionUtils.cpp
1213
ExecutionUtils.cpp
Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
//===------- EPCGenericDylibManager.cpp -- Dylib management via EPC -------===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
#include "llvm/ExecutionEngine/Orc/EPCGenericDylibManager.h"
10+
11+
#include "llvm/ExecutionEngine/Orc/Core.h"
12+
#include "llvm/ExecutionEngine/Orc/Shared/OrcRTBridge.h"
13+
#include "llvm/ExecutionEngine/Orc/Shared/SimpleRemoteEPCUtils.h"
14+
15+
namespace llvm {
16+
namespace orc {
17+
namespace shared {
18+
19+
template <>
20+
class SPSSerializationTraits<SPSRemoteSymbolLookupSetElement,
21+
SymbolLookupSet::value_type> {
22+
public:
23+
static size_t size(const SymbolLookupSet::value_type &V) {
24+
return SPSArgList<SPSString, bool>::size(
25+
*V.first, V.second == SymbolLookupFlags::RequiredSymbol);
26+
}
27+
28+
static bool serialize(SPSOutputBuffer &OB,
29+
const SymbolLookupSet::value_type &V) {
30+
return SPSArgList<SPSString, bool>::serialize(
31+
OB, *V.first, V.second == SymbolLookupFlags::RequiredSymbol);
32+
}
33+
};
34+
35+
template <>
36+
class TrivialSPSSequenceSerialization<SPSRemoteSymbolLookupSetElement,
37+
SymbolLookupSet> {
38+
public:
39+
static constexpr bool available = true;
40+
};
41+
42+
template <>
43+
class SPSSerializationTraits<SPSRemoteSymbolLookup,
44+
ExecutorProcessControl::LookupRequest> {
45+
using MemberSerialization =
46+
SPSArgList<SPSExecutorAddress, SPSRemoteSymbolLookupSet>;
47+
48+
public:
49+
static size_t size(const ExecutorProcessControl::LookupRequest &LR) {
50+
return MemberSerialization::size(ExecutorAddress(LR.Handle), LR.Symbols);
51+
}
52+
53+
static bool serialize(SPSOutputBuffer &OB,
54+
const ExecutorProcessControl::LookupRequest &LR) {
55+
return MemberSerialization::serialize(OB, ExecutorAddress(LR.Handle),
56+
LR.Symbols);
57+
}
58+
};
59+
60+
} // end namespace shared
61+
62+
Expected<EPCGenericDylibManager>
63+
EPCGenericDylibManager::CreateWithDefaultBootstrapSymbols(
64+
ExecutorProcessControl &EPC) {
65+
SymbolAddrs SAs;
66+
if (auto Err = EPC.getBootstrapSymbols(
67+
{{SAs.Instance, rt::SimpleExecutorDylibManagerInstanceName},
68+
{SAs.Open, rt::SimpleExecutorDylibManagerOpenWrapperName},
69+
{SAs.Lookup, rt::SimpleExecutorDylibManagerLookupWrapperName}}))
70+
return std::move(Err);
71+
return EPCGenericDylibManager(EPC, std::move(SAs));
72+
}
73+
74+
Expected<tpctypes::DylibHandle> EPCGenericDylibManager::open(StringRef Path,
75+
uint64_t Mode) {
76+
Expected<tpctypes::DylibHandle> H(0);
77+
if (auto Err =
78+
EPC.callSPSWrapper<rt::SPSSimpleExecutorDylibManagerOpenSignature>(
79+
SAs.Open.getValue(), H, SAs.Instance, Path, Mode))
80+
return std::move(Err);
81+
return H;
82+
}
83+
84+
Expected<std::vector<ExecutorAddress>>
85+
EPCGenericDylibManager::lookup(tpctypes::DylibHandle H,
86+
const SymbolLookupSet &Lookup) {
87+
Expected<std::vector<ExecutorAddress>> Result(
88+
(std::vector<ExecutorAddress>()));
89+
if (auto Err =
90+
EPC.callSPSWrapper<rt::SPSSimpleExecutorDylibManagerLookupSignature>(
91+
SAs.Lookup.getValue(), Result, SAs.Instance, H, Lookup))
92+
return std::move(Err);
93+
return Result;
94+
}
95+
96+
Expected<std::vector<ExecutorAddress>>
97+
EPCGenericDylibManager::lookup(tpctypes::DylibHandle H,
98+
const RemoteSymbolLookupSet &Lookup) {
99+
Expected<std::vector<ExecutorAddress>> Result(
100+
(std::vector<ExecutorAddress>()));
101+
if (auto Err =
102+
EPC.callSPSWrapper<rt::SPSSimpleExecutorDylibManagerLookupSignature>(
103+
SAs.Lookup.getValue(), Result, SAs.Instance, H, Lookup))
104+
return std::move(Err);
105+
return Result;
106+
}
107+
108+
} // end namespace orc
109+
} // end namespace llvm

llvm/lib/ExecutionEngine/Orc/Shared/OrcRTBridge.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,12 @@ namespace llvm {
1212
namespace orc {
1313
namespace rt {
1414

15+
const char *SimpleExecutorDylibManagerInstanceName =
16+
"__llvm_orc_SimpleExecutorDylibManager_Instance";
17+
const char *SimpleExecutorDylibManagerOpenWrapperName =
18+
"__llvm_orc_SimpleExecutorDylibManager_open_wrapper";
19+
const char *SimpleExecutorDylibManagerLookupWrapperName =
20+
"__llvm_orc_SimpleExecutorDylibManager_lookup_wrapper";
1521
const char *SimpleExecutorMemoryManagerInstanceName =
1622
"__llvm_orc_SimpleExecutorMemoryManager_Instance";
1723
const char *SimpleExecutorMemoryManagerReserveWrapperName =

0 commit comments

Comments
 (0)