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