xref: /freebsd/contrib/llvm-project/llvm/lib/ExecutionEngine/Orc/EPCDynamicLibrarySearchGenerator.cpp (revision 27bd6c32bbb49a592a0dfbec5f211a7c2fed31d6)
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 = 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  
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