xref: /src/contrib/llvm-project/llvm/lib/ExecutionEngine/Orc/EPCDynamicLibrarySearchGenerator.cpp (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
1344a3780SDimitry Andric //===---------------- EPCDynamicLibrarySearchGenerator.cpp ----------------===//
2b60736ecSDimitry Andric //
3b60736ecSDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4b60736ecSDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5b60736ecSDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6b60736ecSDimitry Andric //
7b60736ecSDimitry Andric //===----------------------------------------------------------------------===//
8b60736ecSDimitry Andric 
9344a3780SDimitry Andric #include "llvm/ExecutionEngine/Orc/EPCDynamicLibrarySearchGenerator.h"
10ac9a064cSDimitry Andric #include "llvm/ExecutionEngine/Orc/DebugUtils.h"
11ac9a064cSDimitry Andric #include "llvm/Support/Error.h"
12ac9a064cSDimitry Andric 
13ac9a064cSDimitry Andric #define DEBUG_TYPE "orc"
14b60736ecSDimitry Andric 
15b60736ecSDimitry Andric namespace llvm {
16b60736ecSDimitry Andric namespace orc {
17b60736ecSDimitry Andric 
18344a3780SDimitry Andric Expected<std::unique_ptr<EPCDynamicLibrarySearchGenerator>>
Load(ExecutionSession & ES,const char * LibraryPath,SymbolPredicate Allow,AddAbsoluteSymbolsFn AddAbsoluteSymbols)19aca2e42cSDimitry Andric EPCDynamicLibrarySearchGenerator::Load(
20aca2e42cSDimitry Andric     ExecutionSession &ES, const char *LibraryPath, SymbolPredicate Allow,
21aca2e42cSDimitry Andric     AddAbsoluteSymbolsFn AddAbsoluteSymbols) {
22344a3780SDimitry Andric   auto Handle = ES.getExecutorProcessControl().loadDylib(LibraryPath);
23b60736ecSDimitry Andric   if (!Handle)
24b60736ecSDimitry Andric     return Handle.takeError();
25b60736ecSDimitry Andric 
26aca2e42cSDimitry Andric   return std::make_unique<EPCDynamicLibrarySearchGenerator>(
27aca2e42cSDimitry Andric       ES, *Handle, std::move(Allow), std::move(AddAbsoluteSymbols));
28b60736ecSDimitry Andric }
29b60736ecSDimitry Andric 
tryToGenerate(LookupState & LS,LookupKind K,JITDylib & JD,JITDylibLookupFlags JDLookupFlags,const SymbolLookupSet & Symbols)30344a3780SDimitry Andric Error EPCDynamicLibrarySearchGenerator::tryToGenerate(
31b60736ecSDimitry Andric     LookupState &LS, LookupKind K, JITDylib &JD,
32b60736ecSDimitry Andric     JITDylibLookupFlags JDLookupFlags, const SymbolLookupSet &Symbols) {
33b60736ecSDimitry Andric 
34b60736ecSDimitry Andric   if (Symbols.empty())
35b60736ecSDimitry Andric     return Error::success();
36b60736ecSDimitry Andric 
37ac9a064cSDimitry Andric   LLVM_DEBUG({
38ac9a064cSDimitry Andric       dbgs() << "EPCDynamicLibrarySearchGenerator trying to generate "
39ac9a064cSDimitry Andric              << Symbols << "\n";
40ac9a064cSDimitry Andric     });
41ac9a064cSDimitry Andric 
42b60736ecSDimitry Andric   SymbolLookupSet LookupSymbols;
43b60736ecSDimitry Andric 
44b60736ecSDimitry Andric   for (auto &KV : Symbols) {
45b60736ecSDimitry Andric     // Skip symbols that don't match the filter.
46b60736ecSDimitry Andric     if (Allow && !Allow(KV.first))
47b60736ecSDimitry Andric       continue;
48b60736ecSDimitry Andric     LookupSymbols.add(KV.first, SymbolLookupFlags::WeaklyReferencedSymbol);
49b60736ecSDimitry Andric   }
50b60736ecSDimitry Andric 
51344a3780SDimitry Andric   ExecutorProcessControl::LookupRequest Request(H, LookupSymbols);
52ac9a064cSDimitry Andric   // Copy-capture LookupSymbols, since LookupRequest keeps a reference.
53ac9a064cSDimitry Andric   EPC.lookupSymbolsAsync(Request, [this, &JD, LS = std::move(LS),
54ac9a064cSDimitry Andric                                    LookupSymbols](auto Result) mutable {
55ac9a064cSDimitry Andric     if (!Result) {
56ac9a064cSDimitry Andric       LLVM_DEBUG({
57ac9a064cSDimitry Andric         dbgs() << "EPCDynamicLibrarySearchGenerator lookup failed due to error";
58ac9a064cSDimitry Andric       });
59ac9a064cSDimitry Andric       return LS.continueLookup(Result.takeError());
60ac9a064cSDimitry Andric     }
61b60736ecSDimitry Andric 
62b60736ecSDimitry Andric     assert(Result->size() == 1 && "Results for more than one library returned");
63b60736ecSDimitry Andric     assert(Result->front().size() == LookupSymbols.size() &&
64b60736ecSDimitry Andric            "Result has incorrect number of elements");
65b60736ecSDimitry Andric 
66ac9a064cSDimitry Andric     SymbolMap NewSymbols;
67b60736ecSDimitry Andric     auto ResultI = Result->front().begin();
68b60736ecSDimitry Andric     for (auto &KV : LookupSymbols) {
69aca2e42cSDimitry Andric       if (ResultI->getAddress())
70aca2e42cSDimitry Andric         NewSymbols[KV.first] = *ResultI;
71b60736ecSDimitry Andric       ++ResultI;
72b60736ecSDimitry Andric     }
73b60736ecSDimitry Andric 
74ac9a064cSDimitry Andric     LLVM_DEBUG({
75ac9a064cSDimitry Andric       dbgs() << "EPCDynamicLibrarySearchGenerator lookup returned "
76ac9a064cSDimitry Andric              << NewSymbols << "\n";
77ac9a064cSDimitry Andric     });
78ac9a064cSDimitry Andric 
79b60736ecSDimitry Andric     // If there were no resolved symbols bail out.
80b60736ecSDimitry Andric     if (NewSymbols.empty())
81ac9a064cSDimitry Andric       return LS.continueLookup(Error::success());
82b60736ecSDimitry Andric 
83b60736ecSDimitry Andric     // Define resolved symbols.
84ac9a064cSDimitry Andric     Error Err = AddAbsoluteSymbols
85ac9a064cSDimitry Andric                     ? AddAbsoluteSymbols(JD, std::move(NewSymbols))
86ac9a064cSDimitry Andric                     : JD.define(absoluteSymbols(std::move(NewSymbols)));
87ac9a064cSDimitry Andric 
88ac9a064cSDimitry Andric     LS.continueLookup(std::move(Err));
89ac9a064cSDimitry Andric   });
90ac9a064cSDimitry Andric 
91ac9a064cSDimitry Andric   return Error::success();
92b60736ecSDimitry Andric }
93b60736ecSDimitry Andric 
94b60736ecSDimitry Andric } // end namespace orc
95b60736ecSDimitry Andric } // end namespace llvm
96