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