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