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