1//===---- ExecutorProcessControl.cpp -- Executor process control APIs -----===//
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/ExecutorResolutionGenerator.h"
10
11#include "llvm/ExecutionEngine/Orc/DebugUtils.h"
12#include "llvm/Support/Error.h"
13
14#define DEBUG_TYPE "orc"
15
16namespace llvm {
17namespace orc {
18
19Expected<std::unique_ptr<ExecutorResolutionGenerator>>
20ExecutorResolutionGenerator::Load(ExecutionSession &ES, DylibManager &DylibMgr,
21 const char *LibraryPath,
22 SymbolPredicate Allow,
23 AbsoluteSymbolsFn AbsoluteSymbols) {
24 auto H = DylibMgr.loadDylib(DylibPath: LibraryPath);
25 if (H)
26 return H.takeError();
27 return std::make_unique<ExecutorResolutionGenerator>(
28 args&: ES, args&: DylibMgr, args&: *H, args: std::move(Allow), args: std::move(AbsoluteSymbols));
29}
30
31Error ExecutorResolutionGenerator::tryToGenerate(
32 LookupState &LS, LookupKind K, JITDylib &JD,
33 JITDylibLookupFlags JDLookupFlags, const SymbolLookupSet &LookupSet) {
34
35 if (LookupSet.empty())
36 return Error::success();
37
38 LLVM_DEBUG({
39 dbgs() << "ExecutorResolutionGenerator trying to generate " << LookupSet
40 << "\n";
41 });
42
43 SymbolLookupSet LookupSymbols;
44 for (auto &[Name, LookupFlag] : LookupSet) {
45 if (Allow && !Allow(Name))
46 continue;
47 LookupSymbols.add(Name, Flags: LookupFlag);
48 }
49
50 DylibMgr.lookupSymbolsAsync(
51 H, Symbols: LookupSymbols,
52 F: [this, LS = std::move(LS), JD = JITDylibSP(&JD),
53 LookupSymbols](auto Result) mutable {
54 if (Result) {
55 LLVM_DEBUG({
56 dbgs() << "ExecutorResolutionGenerator lookup failed due to error";
57 });
58 return LS.continueLookup(Err: Result.takeError());
59 }
60 assert(Result->size() == LookupSymbols.size() &&
61 "Result has incorrect number of elements");
62
63 auto Syms = Result->begin();
64 SymbolNameSet MissingSymbols;
65 SymbolMap NewSyms;
66 for (auto &[Name, Flags] : LookupSymbols) {
67 const auto &Sym = *Syms++;
68 if (Sym && *Sym)
69 NewSyms[Name] = {*Sym, JITSymbolFlags::Exported};
70 else if (LLVM_UNLIKELY(!Sym &&
71 Flags == SymbolLookupFlags::RequiredSymbol))
72 MissingSymbols.insert(V: Name);
73 }
74
75 LLVM_DEBUG({
76 dbgs() << "ExecutorResolutionGenerator lookup returned " << NewSyms
77 << "\n";
78 });
79
80 if (NewSyms.empty())
81 return LS.continueLookup(Err: Error::success());
82
83 if (LLVM_UNLIKELY(!MissingSymbols.empty()))
84 return LS.continueLookup(Err: make_error<SymbolsNotFound>(
85 Args: this->ES.getSymbolStringPool(), Args: std::move(MissingSymbols)));
86
87 LS.continueLookup(Err: JD->define(MU: AbsoluteSymbols(std::move(NewSyms))));
88 });
89
90 return Error::success();
91}
92
93} // end namespace orc
94} // end namespace llvm
95