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