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