1fe6060f1SDimitry Andric //===---------------- EPCDynamicLibrarySearchGenerator.cpp ----------------===//
2fe6060f1SDimitry Andric //
3fe6060f1SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4fe6060f1SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5fe6060f1SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6fe6060f1SDimitry Andric //
7fe6060f1SDimitry Andric //===----------------------------------------------------------------------===//
8fe6060f1SDimitry Andric
9fe6060f1SDimitry Andric #include "llvm/ExecutionEngine/Orc/EPCDynamicLibrarySearchGenerator.h"
10*0fca6ea1SDimitry Andric #include "llvm/ExecutionEngine/Orc/DebugUtils.h"
11*0fca6ea1SDimitry Andric #include "llvm/Support/Error.h"
12*0fca6ea1SDimitry Andric
13*0fca6ea1SDimitry Andric #define DEBUG_TYPE "orc"
14fe6060f1SDimitry Andric
15fe6060f1SDimitry Andric namespace llvm {
16fe6060f1SDimitry Andric namespace orc {
17fe6060f1SDimitry Andric
18fe6060f1SDimitry Andric Expected<std::unique_ptr<EPCDynamicLibrarySearchGenerator>>
Load(ExecutionSession & ES,const char * LibraryPath,SymbolPredicate Allow,AddAbsoluteSymbolsFn AddAbsoluteSymbols)191db9f3b2SDimitry Andric EPCDynamicLibrarySearchGenerator::Load(
201db9f3b2SDimitry Andric ExecutionSession &ES, const char *LibraryPath, SymbolPredicate Allow,
211db9f3b2SDimitry Andric AddAbsoluteSymbolsFn AddAbsoluteSymbols) {
22fe6060f1SDimitry Andric auto Handle = ES.getExecutorProcessControl().loadDylib(LibraryPath);
23fe6060f1SDimitry Andric if (!Handle)
24fe6060f1SDimitry Andric return Handle.takeError();
25fe6060f1SDimitry Andric
261db9f3b2SDimitry Andric return std::make_unique<EPCDynamicLibrarySearchGenerator>(
271db9f3b2SDimitry Andric ES, *Handle, std::move(Allow), std::move(AddAbsoluteSymbols));
28fe6060f1SDimitry Andric }
29fe6060f1SDimitry Andric
tryToGenerate(LookupState & LS,LookupKind K,JITDylib & JD,JITDylibLookupFlags JDLookupFlags,const SymbolLookupSet & Symbols)30fe6060f1SDimitry Andric Error EPCDynamicLibrarySearchGenerator::tryToGenerate(
31fe6060f1SDimitry Andric LookupState &LS, LookupKind K, JITDylib &JD,
32fe6060f1SDimitry Andric JITDylibLookupFlags JDLookupFlags, const SymbolLookupSet &Symbols) {
33fe6060f1SDimitry Andric
34fe6060f1SDimitry Andric if (Symbols.empty())
35fe6060f1SDimitry Andric return Error::success();
36fe6060f1SDimitry Andric
37*0fca6ea1SDimitry Andric LLVM_DEBUG({
38*0fca6ea1SDimitry Andric dbgs() << "EPCDynamicLibrarySearchGenerator trying to generate "
39*0fca6ea1SDimitry Andric << Symbols << "\n";
40*0fca6ea1SDimitry Andric });
41*0fca6ea1SDimitry Andric
42fe6060f1SDimitry Andric SymbolLookupSet LookupSymbols;
43fe6060f1SDimitry Andric
44fe6060f1SDimitry Andric for (auto &KV : Symbols) {
45fe6060f1SDimitry Andric // Skip symbols that don't match the filter.
46fe6060f1SDimitry Andric if (Allow && !Allow(KV.first))
47fe6060f1SDimitry Andric continue;
48fe6060f1SDimitry Andric LookupSymbols.add(KV.first, SymbolLookupFlags::WeaklyReferencedSymbol);
49fe6060f1SDimitry Andric }
50fe6060f1SDimitry Andric
51fe6060f1SDimitry Andric ExecutorProcessControl::LookupRequest Request(H, LookupSymbols);
52*0fca6ea1SDimitry Andric // Copy-capture LookupSymbols, since LookupRequest keeps a reference.
53*0fca6ea1SDimitry Andric EPC.lookupSymbolsAsync(Request, [this, &JD, LS = std::move(LS),
54*0fca6ea1SDimitry Andric LookupSymbols](auto Result) mutable {
55*0fca6ea1SDimitry Andric if (!Result) {
56*0fca6ea1SDimitry Andric LLVM_DEBUG({
57*0fca6ea1SDimitry Andric dbgs() << "EPCDynamicLibrarySearchGenerator lookup failed due to error";
58*0fca6ea1SDimitry Andric });
59*0fca6ea1SDimitry Andric return LS.continueLookup(Result.takeError());
60*0fca6ea1SDimitry Andric }
61fe6060f1SDimitry Andric
62fe6060f1SDimitry Andric assert(Result->size() == 1 && "Results for more than one library returned");
63fe6060f1SDimitry Andric assert(Result->front().size() == LookupSymbols.size() &&
64fe6060f1SDimitry Andric "Result has incorrect number of elements");
65fe6060f1SDimitry Andric
66*0fca6ea1SDimitry Andric SymbolMap NewSymbols;
67fe6060f1SDimitry Andric auto ResultI = Result->front().begin();
68fe6060f1SDimitry Andric for (auto &KV : LookupSymbols) {
691db9f3b2SDimitry Andric if (ResultI->getAddress())
701db9f3b2SDimitry Andric NewSymbols[KV.first] = *ResultI;
71fe6060f1SDimitry Andric ++ResultI;
72fe6060f1SDimitry Andric }
73fe6060f1SDimitry Andric
74*0fca6ea1SDimitry Andric LLVM_DEBUG({
75*0fca6ea1SDimitry Andric dbgs() << "EPCDynamicLibrarySearchGenerator lookup returned "
76*0fca6ea1SDimitry Andric << NewSymbols << "\n";
77*0fca6ea1SDimitry Andric });
78*0fca6ea1SDimitry Andric
79fe6060f1SDimitry Andric // If there were no resolved symbols bail out.
80fe6060f1SDimitry Andric if (NewSymbols.empty())
81*0fca6ea1SDimitry Andric return LS.continueLookup(Error::success());
82fe6060f1SDimitry Andric
83fe6060f1SDimitry Andric // Define resolved symbols.
84*0fca6ea1SDimitry Andric Error Err = AddAbsoluteSymbols
85*0fca6ea1SDimitry Andric ? AddAbsoluteSymbols(JD, std::move(NewSymbols))
86*0fca6ea1SDimitry Andric : JD.define(absoluteSymbols(std::move(NewSymbols)));
87*0fca6ea1SDimitry Andric
88*0fca6ea1SDimitry Andric LS.continueLookup(std::move(Err));
89*0fca6ea1SDimitry Andric });
90*0fca6ea1SDimitry Andric
91*0fca6ea1SDimitry Andric return Error::success();
92fe6060f1SDimitry Andric }
93fe6060f1SDimitry Andric
94fe6060f1SDimitry Andric } // end namespace orc
95fe6060f1SDimitry Andric } // end namespace llvm
96