xref: /freebsd/contrib/llvm-project/llvm/lib/ExecutionEngine/Orc/EPCDynamicLibrarySearchGenerator.cpp (revision 770cf0a5f02dc8983a89c6568d741fbc25baa999)
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   // If there's no handle then resolve all requested symbols to null.
46   if (!H) {
47     assert(Allow && "No handle or filter?");
48     SymbolMap Nulls;
49     for (auto &[Name, LookupFlags] : Symbols) {
50       if (Allow(Name))
51         Nulls[Name] = {};
52     }
53     return addAbsolutes(JD, std::move(Nulls));
54   }
55 
56   // Otherwise proceed with lookup in the remote.
57   SymbolLookupSet LookupSymbols;
58 
59   for (auto &KV : Symbols) {
60     // Skip symbols that don't match the filter.
61     if (Allow && !Allow(KV.first))
62       continue;
63     LookupSymbols.add(KV.first, SymbolLookupFlags::WeaklyReferencedSymbol);
64   }
65 
66   DylibManager::LookupRequest Request(*H, LookupSymbols);
67   // Copy-capture LookupSymbols, since LookupRequest keeps a reference.
68   EPC.getDylibMgr().lookupSymbolsAsync(Request, [this, &JD, LS = std::move(LS),
69                                                  LookupSymbols](
70                                                     auto Result) mutable {
71     if (!Result) {
72       LLVM_DEBUG({
73         dbgs() << "EPCDynamicLibrarySearchGenerator lookup failed due to error";
74       });
75       return LS.continueLookup(Result.takeError());
76     }
77 
78     assert(Result->size() == 1 && "Results for more than one library returned");
79     assert(Result->front().size() == LookupSymbols.size() &&
80            "Result has incorrect number of elements");
81 
82     SymbolMap NewSymbols;
83     auto ResultI = Result->front().begin();
84     for (auto &KV : LookupSymbols) {
85       if (ResultI->getAddress())
86         NewSymbols[KV.first] = *ResultI;
87       ++ResultI;
88     }
89 
90     LLVM_DEBUG({
91       dbgs() << "EPCDynamicLibrarySearchGenerator lookup returned "
92              << NewSymbols << "\n";
93     });
94 
95     // If there were no resolved symbols bail out.
96     if (NewSymbols.empty())
97       return LS.continueLookup(Error::success());
98 
99     // Define resolved symbols.
100     Error Err = addAbsolutes(JD, std::move(NewSymbols));
101 
102     LS.continueLookup(std::move(Err));
103   });
104 
105   return Error::success();
106 }
107 
108 Error EPCDynamicLibrarySearchGenerator::addAbsolutes(JITDylib &JD,
109                                                      SymbolMap Symbols) {
110   return AddAbsoluteSymbols ? AddAbsoluteSymbols(JD, std::move(Symbols))
111                             : JD.define(absoluteSymbols(std::move(Symbols)));
112 }
113 
114 } // end namespace orc
115 } // end namespace llvm
116