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