1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
|
//===---------------- EPCDynamicLibrarySearchGenerator.cpp ----------------===//
//
// 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/EPCDynamicLibrarySearchGenerator.h"
#include "llvm/ExecutionEngine/Orc/AbsoluteSymbols.h"
#include "llvm/ExecutionEngine/Orc/DebugUtils.h"
#include "llvm/Support/Error.h"
#define DEBUG_TYPE "orc"
namespace llvm {
namespace orc {
Expected<std::unique_ptr<EPCDynamicLibrarySearchGenerator>>
EPCDynamicLibrarySearchGenerator::Load(
ExecutionSession &ES, const char *LibraryPath, SymbolPredicate Allow,
AddAbsoluteSymbolsFn AddAbsoluteSymbols) {
auto Handle =
ES.getExecutorProcessControl().getDylibMgr().loadDylib(LibraryPath);
if (!Handle)
return Handle.takeError();
return std::make_unique<EPCDynamicLibrarySearchGenerator>(
ES, *Handle, std::move(Allow), std::move(AddAbsoluteSymbols));
}
Error EPCDynamicLibrarySearchGenerator::tryToGenerate(
LookupState &LS, LookupKind K, JITDylib &JD,
JITDylibLookupFlags JDLookupFlags, const SymbolLookupSet &Symbols) {
if (Symbols.empty())
return Error::success();
LLVM_DEBUG({
dbgs() << "EPCDynamicLibrarySearchGenerator trying to generate "
<< Symbols << "\n";
});
// If there's no handle then resolve all requested symbols to null.
if (!H) {
assert(Allow && "No handle or filter?");
SymbolMap Nulls;
for (auto &[Name, LookupFlags] : Symbols) {
if (Allow(Name))
Nulls[Name] = {};
}
return addAbsolutes(JD, std::move(Nulls));
}
// Otherwise proceed with lookup in the remote.
SymbolLookupSet LookupSymbols;
for (auto &KV : Symbols) {
// Skip symbols that don't match the filter.
if (Allow && !Allow(KV.first))
continue;
LookupSymbols.add(KV.first, SymbolLookupFlags::WeaklyReferencedSymbol);
}
DylibManager::LookupRequest Request(*H, LookupSymbols);
// Copy-capture LookupSymbols, since LookupRequest keeps a reference.
EPC.getDylibMgr().lookupSymbolsAsync(Request, [this, &JD, LS = std::move(LS),
LookupSymbols](
auto Result) mutable {
if (!Result) {
LLVM_DEBUG({
dbgs() << "EPCDynamicLibrarySearchGenerator lookup failed due to error";
});
return LS.continueLookup(Result.takeError());
}
assert(Result->size() == 1 && "Results for more than one library returned");
assert(Result->front().size() == LookupSymbols.size() &&
"Result has incorrect number of elements");
SymbolMap NewSymbols;
auto ResultI = Result->front().begin();
for (auto &KV : LookupSymbols) {
if (ResultI->getAddress())
NewSymbols[KV.first] = *ResultI;
++ResultI;
}
LLVM_DEBUG({
dbgs() << "EPCDynamicLibrarySearchGenerator lookup returned "
<< NewSymbols << "\n";
});
// If there were no resolved symbols bail out.
if (NewSymbols.empty())
return LS.continueLookup(Error::success());
// Define resolved symbols.
Error Err = addAbsolutes(JD, std::move(NewSymbols));
LS.continueLookup(std::move(Err));
});
return Error::success();
}
Error EPCDynamicLibrarySearchGenerator::addAbsolutes(JITDylib &JD,
SymbolMap Symbols) {
return AddAbsoluteSymbols ? AddAbsoluteSymbols(JD, std::move(Symbols))
: JD.define(absoluteSymbols(std::move(Symbols)));
}
} // end namespace orc
} // end namespace llvm
|