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 DylibManager::LookupRequest LR(H, LookupSymbols);
52 DylibMgr.lookupSymbolsAsync(
53 Request: LR, 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() == 1 &&
62 "Results for more than one library returned");
63 assert(Result->front().size() == LookupSymbols.size() &&
64 "Result has incorrect number of elements");
65
66 // const tpctypes::LookupResult &Syms = Result->front();
67 // size_t SymIdx = 0;
68 auto Syms = Result->front().begin();
69 SymbolNameSet MissingSymbols;
70 SymbolMap NewSyms;
71 for (auto &[Name, Flags] : LookupSymbols) {
72 const auto &Sym = *Syms++;
73 if (Sym && Sym->getAddress())
74 NewSyms[Name] = *Sym;
75 else if (LLVM_UNLIKELY(!Sym &&
76 Flags == SymbolLookupFlags::RequiredSymbol))
77 MissingSymbols.insert(V: Name);
78 }
79
80 LLVM_DEBUG({
81 dbgs() << "ExecutorResolutionGenerator lookup returned " << NewSyms
82 << "\n";
83 });
84
85 if (NewSyms.empty())
86 return LS.continueLookup(Err: Error::success());
87
88 if (LLVM_UNLIKELY(!MissingSymbols.empty()))
89 return LS.continueLookup(Err: make_error<SymbolsNotFound>(
90 Args: this->ES.getSymbolStringPool(), Args: std::move(MissingSymbols)));
91
92 LS.continueLookup(Err: JD->define(MU: AbsoluteSymbols(std::move(NewSyms))));
93 });
94
95 return Error::success();
96}
97
98} // end namespace orc
99} // end namespace llvm
100