xref: /freebsd/contrib/llvm-project/llvm/lib/ExecutionEngine/Orc/EPCDynamicLibrarySearchGenerator.cpp (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
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>>
Load(ExecutionSession & ES,const char * LibraryPath,SymbolPredicate Allow,AddAbsoluteSymbolsFn AddAbsoluteSymbols)19 EPCDynamicLibrarySearchGenerator::Load(
20     ExecutionSession &ES, const char *LibraryPath, SymbolPredicate Allow,
21     AddAbsoluteSymbolsFn AddAbsoluteSymbols) {
22   auto Handle = ES.getExecutorProcessControl().loadDylib(LibraryPath);
23   if (!Handle)
24     return Handle.takeError();
25 
26   return std::make_unique<EPCDynamicLibrarySearchGenerator>(
27       ES, *Handle, std::move(Allow), std::move(AddAbsoluteSymbols));
28 }
29 
tryToGenerate(LookupState & LS,LookupKind K,JITDylib & JD,JITDylibLookupFlags JDLookupFlags,const SymbolLookupSet & Symbols)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(KV.first, SymbolLookupFlags::WeaklyReferencedSymbol);
49   }
50 
51   ExecutorProcessControl::LookupRequest Request(H, LookupSymbols);
52   // Copy-capture LookupSymbols, since LookupRequest keeps a reference.
53   EPC.lookupSymbolsAsync(Request, [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(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(Error::success());
82 
83     // Define resolved symbols.
84     Error Err = AddAbsoluteSymbols
85                     ? AddAbsoluteSymbols(JD, std::move(NewSymbols))
86                     : JD.define(absoluteSymbols(std::move(NewSymbols)));
87 
88     LS.continueLookup(std::move(Err));
89   });
90 
91   return Error::success();
92 }
93 
94 } // end namespace orc
95 } // end namespace llvm
96