Skip to content

Commit 3a67e8a

Browse files
committed
[ORC] Add Resolver API
1 parent d8c8c67 commit 3a67e8a

14 files changed

+340
-20
lines changed

llvm/include/llvm/ExecutionEngine/Orc/EPCGenericDylibManager.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ class EPCGenericDylibManager {
3535
ExecutorAddr Instance;
3636
ExecutorAddr Open;
3737
ExecutorAddr Lookup;
38+
ExecutorAddr Resolve;
3839
};
3940

4041
/// Create an EPCGenericMemoryAccess instance from a given set of
@@ -68,8 +69,8 @@ class EPCGenericDylibManager {
6869
return RF.get();
6970
}
7071

71-
using SymbolLookupCompleteFn =
72-
unique_function<void(Expected<std::vector<ExecutorSymbolDef>>)>;
72+
using SymbolLookupCompleteFn = unique_function<void(
73+
Expected<std::vector<ExecutorSymbolDef>>)>;
7374

7475
/// Looks up symbols within the given dylib.
7576
LLVM_ABI void lookupAsync(tpctypes::DylibHandle H,
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
2+
// LLVM_EXECUTIONENGINE_ORC_EXECUTORRESOLUTIONGENERATOR_H
3+
//===----- ExecutorResolver.h - Resolve symbols in executor -----*- C++ -*-===//
4+
//
5+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
6+
// See https://llvm.org/LICENSE.txt for license information.
7+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
8+
//
9+
//===----------------------------------------------------------------------===//
10+
//
11+
// Declares ExecutorResolutionGenerator for symbol resolution,
12+
// dynamic library loading, and lookup in an executor process via
13+
// ExecutorResolver.
14+
//
15+
//===----------------------------------------------------------------------===//
16+
17+
#ifndef LLVM_EXECUTIONENGINE_ORC_EXECUTORRESOLUTIONGENERATOR_H
18+
#define LLVM_EXECUTIONENGINE_ORC_EXECUTORRESOLUTIONGENERATOR_H
19+
20+
#include "llvm/ADT/FunctionExtras.h"
21+
#include "llvm/ExecutionEngine/Orc/AbsoluteSymbols.h"
22+
#include "llvm/ExecutionEngine/Orc/Core.h"
23+
24+
namespace llvm::orc {
25+
26+
class ExecutorResolutionGenerator : public DefinitionGenerator {
27+
public:
28+
using SymbolPredicate = unique_function<bool(const SymbolStringPtr &)>;
29+
using AbsoluteSymbolsFn =
30+
unique_function<std::unique_ptr<MaterializationUnit>(SymbolMap)>;
31+
32+
ExecutorResolutionGenerator(
33+
ExecutionSession &ES, tpctypes::ResolverHandle H,
34+
SymbolPredicate Allow = SymbolPredicate(),
35+
AbsoluteSymbolsFn AbsoluteSymbols = absoluteSymbols)
36+
: EPC(ES.getExecutorProcessControl()), H(H), Allow(std::move(Allow)),
37+
AbsoluteSymbols(std::move(AbsoluteSymbols)) {}
38+
39+
ExecutorResolutionGenerator(
40+
ExecutionSession &ES, SymbolPredicate Allow = SymbolPredicate(),
41+
AbsoluteSymbolsFn AbsoluteSymbols = absoluteSymbols)
42+
: EPC(ES.getExecutorProcessControl()), Allow(std::move(Allow)),
43+
AbsoluteSymbols(std::move(AbsoluteSymbols)) {}
44+
45+
/// Permanently loads the library at the given path and, on success, returns
46+
/// an ExecutorResolutionGenerator that will search it for symbol
47+
/// definitions in the library. On failure returns the reason the library
48+
/// failed to load.
49+
static Expected<std::unique_ptr<ExecutorResolutionGenerator>>
50+
Load(ExecutionSession &ES, const char *LibraryPath,
51+
SymbolPredicate Allow = SymbolPredicate(),
52+
AbsoluteSymbolsFn AbsoluteSymbols = absoluteSymbols);
53+
54+
/// Creates a ExecutorResolutionGenerator that searches for symbols in
55+
/// the target process.
56+
static Expected<std::unique_ptr<ExecutorResolutionGenerator>>
57+
GetForTargetProcess(ExecutionSession &ES,
58+
SymbolPredicate Allow = SymbolPredicate(),
59+
AbsoluteSymbolsFn AbsoluteSymbols = absoluteSymbols) {
60+
return Load(ES, nullptr, std::move(Allow), std::move(AbsoluteSymbols));
61+
}
62+
63+
Error tryToGenerate(LookupState &LS, LookupKind K, JITDylib &JD,
64+
JITDylibLookupFlags JDLookupFlags,
65+
const SymbolLookupSet &LookupSet) override;
66+
67+
private:
68+
ExecutorProcessControl &EPC;
69+
tpctypes::ResolverHandle H;
70+
SymbolPredicate Allow;
71+
AbsoluteSymbolsFn AbsoluteSymbols;
72+
};
73+
74+
} // namespace llvm::orc
75+
76+
#endif // LLVM_EXECUTIONENGINE_ORC_EXECUTORRESOLUTIONGENERATOR_H

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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ namespace rt {
2626
LLVM_ABI extern const char *SimpleExecutorDylibManagerInstanceName;
2727
LLVM_ABI extern const char *SimpleExecutorDylibManagerOpenWrapperName;
2828
LLVM_ABI extern const char *SimpleExecutorDylibManagerLookupWrapperName;
29+
LLVM_ABI extern const char *SimpleExecutorDylibManagerResolveWrapperName;
2930

3031
LLVM_ABI extern const char *SimpleExecutorMemoryManagerInstanceName;
3132
LLVM_ABI extern const char *SimpleExecutorMemoryManagerReserveWrapperName;
@@ -71,6 +72,10 @@ using SPSSimpleExecutorDylibManagerLookupSignature =
7172
shared::SPSExecutorAddr, shared::SPSExecutorAddr,
7273
shared::SPSRemoteSymbolLookupSet);
7374

75+
using SPSSimpleExecutorDylibManagerResolveSignature =
76+
shared::SPSExpected<shared::SPSSequence<shared::SPSExecutorSymbolDef>>(
77+
shared::SPSExecutorAddr, shared::SPSRemoteSymbolLookupSet);
78+
7479
using SPSSimpleExecutorMemoryManagerReserveSignature =
7580
shared::SPSExpected<shared::SPSExecutorAddr>(shared::SPSExecutorAddr,
7681
uint64_t);

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,10 @@ struct PointerWrite {
114114
/// A handle used to represent a loaded dylib in the target process.
115115
using DylibHandle = ExecutorAddr;
116116

117+
/// A handle used to reference the resolver associated with a loaded
118+
/// dylib in the target process.
119+
using ResolverHandle = ExecutorAddr;
120+
117121
using LookupResult = std::vector<ExecutorSymbolDef>;
118122

119123
} // end namespace tpctypes
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
//===----- ExecutorResolver.h - Symbol resolver -----*- 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+
// Executor Symbol resolver.
10+
//
11+
//===----------------------------------------------------------------------===//
12+
13+
#ifndef LLVM_EXECUTIONENGINE_ORC_TARGETPROCESS_EXECUTORRESOLVER_H
14+
#define LLVM_EXECUTIONENGINE_ORC_TARGETPROCESS_EXECUTORRESOLVER_H
15+
16+
#include "llvm/ADT/FunctionExtras.h"
17+
18+
#include "llvm/ExecutionEngine/Orc/Shared/ExecutorSymbolDef.h"
19+
#include "llvm/ExecutionEngine/Orc/Shared/SimpleRemoteEPCUtils.h"
20+
#include "llvm/ExecutionEngine/Orc/Shared/TargetProcessControlTypes.h"
21+
22+
namespace llvm::orc {
23+
24+
class ExecutorResolver {
25+
public:
26+
using ResolveResult = Expected<std::vector<ExecutorSymbolDef>>;
27+
using YieldResolveResultFn = unique_function<void(ResolveResult)>;
28+
29+
virtual ~ExecutorResolver() = default;
30+
31+
virtual void resolveAsync(const RemoteSymbolLookupSet &L,
32+
YieldResolveResultFn &&OnResolve) = 0;
33+
};
34+
35+
class DylibSymbolResolver : public ExecutorResolver {
36+
public:
37+
DylibSymbolResolver(tpctypes::DylibHandle H)
38+
: Handle(H) {}
39+
40+
void resolveAsync(const RemoteSymbolLookupSet &L,
41+
ExecutorResolver::YieldResolveResultFn &&OnResolve) override;
42+
43+
private:
44+
tpctypes::DylibHandle Handle;
45+
};
46+
47+
} // end namespace llvm::orc
48+
#endif // LLVM_EXECUTIONENGINE_ORC_TARGETPROCESS_EXECUTORRESOLVER_H

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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
#include "llvm/ExecutionEngine/Orc/Shared/TargetProcessControlTypes.h"
2424
#include "llvm/ExecutionEngine/Orc/Shared/WrapperFunctionUtils.h"
2525
#include "llvm/ExecutionEngine/Orc/TargetProcess/ExecutorBootstrapService.h"
26+
#include "llvm/ExecutionEngine/Orc/TargetProcess/ExecutorResolver.h"
2627
#include "llvm/Support/Compiler.h"
2728
#include "llvm/Support/DynamicLibrary.h"
2829
#include "llvm/Support/Error.h"
@@ -54,8 +55,12 @@ class LLVM_ABI SimpleExecutorDylibManager : public ExecutorBootstrapService {
5455
static llvm::orc::shared::CWrapperFunctionResult
5556
lookupWrapper(const char *ArgData, size_t ArgSize);
5657

58+
static llvm::orc::shared::CWrapperFunctionResult
59+
resolveWrapper(const char *ArgData, size_t ArgSize);
60+
5761
std::mutex M;
5862
DylibSet Dylibs;
63+
std::vector<std::unique_ptr<ExecutorResolver>> Resolvers;
5964
};
6065

6166
} // end namespace rt_bootstrap

llvm/lib/ExecutionEngine/Orc/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ add_llvm_component_library(LLVMOrcJIT
2424
EPCGenericRTDyldMemoryManager.cpp
2525
EPCIndirectionUtils.cpp
2626
ExecutionUtils.cpp
27+
ExecutorResolutionGenerator.cpp
2728
ObjectFileInterface.cpp
2829
GetDylibInterface.cpp
2930
IndirectionUtils.cpp

llvm/lib/ExecutionEngine/Orc/EPCDynamicLibrarySearchGenerator.cpp

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -79,25 +79,32 @@ Error EPCDynamicLibrarySearchGenerator::tryToGenerate(
7979
assert(Result->front().size() == LookupSymbols.size() &&
8080
"Result has incorrect number of elements");
8181

82-
SymbolMap NewSymbols;
83-
auto ResultI = Result->front().begin();
84-
for (auto &KV : LookupSymbols) {
85-
if (ResultI->getAddress())
86-
NewSymbols[KV.first] = *ResultI;
87-
++ResultI;
82+
const std::vector<ExecutorSymbolDef> &Syms = Result->front();
83+
size_t SymIdx = 0;
84+
SymbolNameSet MissingSymbols;
85+
SymbolMap NewSyms;
86+
for (auto &[Name, Flags] : LookupSymbols) {
87+
auto Sym = Syms[SymIdx++];
88+
if (Sym.getAddress())
89+
NewSyms[Name] = Sym;
90+
else if (LLVM_UNLIKELY(Flags == SymbolLookupFlags::RequiredSymbol))
91+
MissingSymbols.insert(Name);
8892
}
8993

9094
LLVM_DEBUG({
9195
dbgs() << "EPCDynamicLibrarySearchGenerator lookup returned "
92-
<< NewSymbols << "\n";
96+
<< NewSyms << "\n";
9397
});
9498

95-
// If there were no resolved symbols bail out.
96-
if (NewSymbols.empty())
99+
if (NewSyms.empty())
97100
return LS.continueLookup(Error::success());
98101

102+
if (LLVM_UNLIKELY(!MissingSymbols.empty()))
103+
return LS.continueLookup(make_error<SymbolsNotFound>(
104+
this->EPC.getSymbolStringPool(), std::move(MissingSymbols)));
105+
99106
// Define resolved symbols.
100-
Error Err = addAbsolutes(JD, std::move(NewSymbols));
107+
Error Err = addAbsolutes(JD, std::move(NewSyms));
101108

102109
LS.continueLookup(std::move(Err));
103110
});

llvm/lib/ExecutionEngine/Orc/EPCGenericDylibManager.cpp

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,8 @@ EPCGenericDylibManager::CreateWithDefaultBootstrapSymbols(
6666
if (auto Err = EPC.getBootstrapSymbols(
6767
{{SAs.Instance, rt::SimpleExecutorDylibManagerInstanceName},
6868
{SAs.Open, rt::SimpleExecutorDylibManagerOpenWrapperName},
69-
{SAs.Lookup, rt::SimpleExecutorDylibManagerLookupWrapperName}}))
69+
{SAs.Lookup, rt::SimpleExecutorDylibManagerLookupWrapperName},
70+
{SAs.Resolve, rt::SimpleExecutorDylibManagerResolveWrapperName}}))
7071
return std::move(Err);
7172
return EPCGenericDylibManager(EPC, std::move(SAs));
7273
}
@@ -84,8 +85,8 @@ Expected<tpctypes::DylibHandle> EPCGenericDylibManager::open(StringRef Path,
8485
void EPCGenericDylibManager::lookupAsync(tpctypes::DylibHandle H,
8586
const SymbolLookupSet &Lookup,
8687
SymbolLookupCompleteFn Complete) {
87-
EPC.callSPSWrapperAsync<rt::SPSSimpleExecutorDylibManagerLookupSignature>(
88-
SAs.Lookup,
88+
EPC.callSPSWrapperAsync<rt::SPSSimpleExecutorDylibManagerResolveSignature>(
89+
SAs.Resolve,
8990
[Complete = std::move(Complete)](
9091
Error SerializationErr,
9192
Expected<std::vector<ExecutorSymbolDef>> Result) mutable {
@@ -96,14 +97,14 @@ void EPCGenericDylibManager::lookupAsync(tpctypes::DylibHandle H,
9697
}
9798
Complete(std::move(Result));
9899
},
99-
SAs.Instance, H, Lookup);
100+
H, Lookup);
100101
}
101102

102103
void EPCGenericDylibManager::lookupAsync(tpctypes::DylibHandle H,
103104
const RemoteSymbolLookupSet &Lookup,
104105
SymbolLookupCompleteFn Complete) {
105-
EPC.callSPSWrapperAsync<rt::SPSSimpleExecutorDylibManagerLookupSignature>(
106-
SAs.Lookup,
106+
EPC.callSPSWrapperAsync<rt::SPSSimpleExecutorDylibManagerResolveSignature>(
107+
SAs.Resolve,
107108
[Complete = std::move(Complete)](
108109
Error SerializationErr,
109110
Expected<std::vector<ExecutorSymbolDef>> Result) mutable {
@@ -114,7 +115,7 @@ void EPCGenericDylibManager::lookupAsync(tpctypes::DylibHandle H,
114115
}
115116
Complete(std::move(Result));
116117
},
117-
SAs.Instance, H, Lookup);
118+
H, Lookup);
118119
}
119120

120121
} // end namespace orc
Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
//===---- ExecutorProcessControl.cpp -- Executor process control APIs -----===//
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/ExecutorResolutionGenerator.h"
10+
11+
#include "llvm/ExecutionEngine/Orc/DebugUtils.h"
12+
#include "llvm/ExecutionEngine/Orc/Shared/ExecutorSymbolDef.h"
13+
#include "llvm/Support/Error.h"
14+
15+
#define DEBUG_TYPE "orc"
16+
17+
namespace llvm {
18+
namespace orc {
19+
20+
Expected<std::unique_ptr<ExecutorResolutionGenerator>>
21+
ExecutorResolutionGenerator::Load(ExecutionSession &ES, const char *LibraryPath,
22+
SymbolPredicate Allow,
23+
AbsoluteSymbolsFn AbsoluteSymbols) {
24+
auto H = ES.getExecutorProcessControl().getDylibMgr().loadDylib(LibraryPath);
25+
if (H)
26+
return H.takeError();
27+
return std::make_unique<ExecutorResolutionGenerator>(
28+
ES, *H, std::move(Allow), std::move(AbsoluteSymbols));
29+
}
30+
31+
Error ExecutorResolutionGenerator::tryToGenerate(
32+
LookupState &LS, LookupKind K, JITDylib &JD,
33+
JITDylibLookupFlags JDLookupFlags, const SymbolLookupSet &LookupSet) {
34+
35+
if (LookupSet.empty())
36+
return Error::success();
37+
38+
LLVM_DEBUG({
39+
dbgs() << "ExecutorResolutionGenerator trying to generate " << LookupSet
40+
<< "\n";
41+
});
42+
43+
SymbolLookupSet LookupSymbols;
44+
for (auto &[Name, LookupFlag] : LookupSet) {
45+
if (Allow && !Allow(Name))
46+
continue;
47+
LookupSymbols.add(Name, LookupFlag);
48+
}
49+
50+
DylibManager::LookupRequest LR(H, LookupSymbols);
51+
EPC.getDylibMgr().lookupSymbolsAsync(
52+
LR, [this, LS = std::move(LS), JD = JITDylibSP(&JD),
53+
LookupSymbols](auto Result) mutable {
54+
if (Result) {
55+
LLVM_DEBUG({
56+
dbgs() << "ExecutorResolutionGenerator lookup failed due to error";
57+
});
58+
return LS.continueLookup(Result.takeError());
59+
}
60+
assert(Result->size() == 1 &&
61+
"Results for more than one library returned");
62+
assert(Result->front().size() == LookupSymbols.size() &&
63+
"Result has incorrect number of elements");
64+
65+
const std::vector<ExecutorSymbolDef> &Syms = Result->front();
66+
size_t SymIdx = 0;
67+
SymbolNameSet MissingSymbols;
68+
SymbolMap NewSyms;
69+
for (auto &[Name, Flags] : LookupSymbols) {
70+
auto Sym = Syms[SymIdx++];
71+
if (Sym.getAddress())
72+
NewSyms[Name] = Sym;
73+
else if (LLVM_UNLIKELY(Flags == SymbolLookupFlags::RequiredSymbol))
74+
MissingSymbols.insert(Name);
75+
}
76+
77+
LLVM_DEBUG({
78+
dbgs() << "ExecutorResolutionGenerator lookup returned " << NewSyms
79+
<< "\n";
80+
});
81+
82+
if (NewSyms.empty())
83+
return LS.continueLookup(Error::success());
84+
85+
if (LLVM_UNLIKELY(!MissingSymbols.empty()))
86+
return LS.continueLookup(make_error<SymbolsNotFound>(
87+
this->EPC.getSymbolStringPool(), std::move(MissingSymbols)));
88+
89+
LS.continueLookup(JD->define(AbsoluteSymbols(std::move(NewSyms))));
90+
});
91+
92+
return Error::success();
93+
}
94+
95+
} // end namespace orc
96+
} // end namespace llvm

0 commit comments

Comments
 (0)