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