1//===------- EPCGenericDylibManager.cpp -- Dylib management via EPC -------===//
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/EPCGenericDylibManager.h"
10
11#include "llvm/ExecutionEngine/Orc/Core.h"
12#include "llvm/ExecutionEngine/Orc/LookupAndRecordAddrs.h"
13#include "llvm/ExecutionEngine/Orc/Shared/OrcRTBridge.h"
14#include "llvm/ExecutionEngine/Orc/Shared/SimpleRemoteEPCUtils.h"
15
16namespace llvm {
17namespace orc {
18namespace shared {
19
20template <>
21class SPSSerializationTraits<SPSRemoteSymbolLookupSetElement,
22 SymbolLookupSet::value_type> {
23public:
24 static size_t size(const SymbolLookupSet::value_type &V) {
25 return SPSArgList<SPSString, bool>::size(
26 Arg: *V.first, Args: V.second == SymbolLookupFlags::RequiredSymbol);
27 }
28
29 static bool serialize(SPSOutputBuffer &OB,
30 const SymbolLookupSet::value_type &V) {
31 return SPSArgList<SPSString, bool>::serialize(
32 OB, Arg: *V.first, Args: V.second == SymbolLookupFlags::RequiredSymbol);
33 }
34};
35
36template <>
37class TrivialSPSSequenceSerialization<SPSRemoteSymbolLookupSetElement,
38 SymbolLookupSet> {
39public:
40 static constexpr bool available = true;
41};
42
43} // end namespace shared
44
45Expected<EPCGenericDylibManager>
46EPCGenericDylibManager::CreateWithDefaultBootstrapSymbols(
47 ExecutorProcessControl &EPC) {
48 SymbolAddrs SAs;
49 if (auto Err = EPC.getBootstrapSymbols(
50 Pairs: {{SAs.Instance, rt::SimpleExecutorDylibManagerInstanceName},
51 {SAs.Open, rt::SimpleExecutorDylibManagerOpenWrapperName},
52 {SAs.Resolve, rt::SimpleExecutorDylibManagerResolveWrapperName}}))
53 return std::move(Err);
54 return EPCGenericDylibManager(EPC, std::move(SAs));
55}
56
57Expected<EPCGenericDylibManager>
58EPCGenericDylibManager::Create(JITDylib &JD,
59 rt::SimpleExecutorDylibManagerSymbolNames SNs) {
60 auto &ES = JD.getExecutionSession();
61 SymbolAddrs SAs;
62 if (auto Err = lookupAndRecordAddrs(
63 ES, K: LookupKind::Static, SearchOrder: makeJITDylibSearchOrder(JDs: {&JD}),
64 Pairs: {
65 {ES.intern(SymName: SNs.InstanceName), &SAs.Instance},
66 {ES.intern(SymName: SNs.OpenName), &SAs.Open},
67 {ES.intern(SymName: SNs.ResolveName), &SAs.Resolve},
68 }))
69 return std::move(Err);
70 return EPCGenericDylibManager(ES.getExecutorProcessControl(), std::move(SAs));
71}
72
73Expected<EPCGenericDylibManager>
74EPCGenericDylibManager::Create(ExecutionSession &ES,
75 rt::SimpleExecutorDylibManagerSymbolNames SNs) {
76 return Create(JD&: ES.getBootstrapJITDylib(), SNs: std::move(SNs));
77}
78
79Expected<tpctypes::DylibHandle> EPCGenericDylibManager::open(StringRef Path,
80 uint64_t Mode) {
81 Expected<tpctypes::DylibHandle> H((ExecutorAddr()));
82 if (auto Err =
83 EPC.callSPSWrapper<rt::SPSSimpleExecutorDylibManagerOpenSignature>(
84 WrapperFnAddr: SAs.Open, WrapperCallArgs&: H, WrapperCallArgs&: SAs.Instance, WrapperCallArgs&: Path, WrapperCallArgs&: Mode))
85 return std::move(Err);
86 return H;
87}
88
89void EPCGenericDylibManager::lookupAsync(tpctypes::DylibHandle H,
90 const SymbolLookupSet &Lookup,
91 SymbolLookupCompleteFn Complete) {
92 EPC.callSPSWrapperAsync<rt::SPSSimpleExecutorDylibManagerResolveSignature>(
93 WrapperFnAddr: SAs.Resolve,
94 SendResult: [Complete = std::move(Complete)](
95 Error SerializationErr,
96 Expected<std::vector<std::optional<ExecutorAddr>>> Result) mutable {
97 if (SerializationErr) {
98 cantFail(Err: Result.takeError());
99 Complete(std::move(SerializationErr));
100 return;
101 }
102 Complete(std::move(Result));
103 },
104 Args: SAs.Instance, Args: H, Args: Lookup);
105}
106
107void EPCGenericDylibManager::lookupAsync(tpctypes::DylibHandle H,
108 const RemoteSymbolLookupSet &Lookup,
109 SymbolLookupCompleteFn Complete) {
110 EPC.callSPSWrapperAsync<rt::SPSSimpleExecutorDylibManagerResolveSignature>(
111 WrapperFnAddr: SAs.Resolve,
112 SendResult: [Complete = std::move(Complete)](
113 Error SerializationErr,
114 Expected<std::vector<std::optional<ExecutorAddr>>> Result) mutable {
115 if (SerializationErr) {
116 cantFail(Err: Result.takeError());
117 Complete(std::move(SerializationErr));
118 return;
119 }
120 Complete(std::move(Result));
121 },
122 Args: SAs.Instance, Args: H, Args: Lookup);
123}
124
125Expected<tpctypes::DylibHandle>
126EPCGenericDylibManager::loadDylib(const char *DylibPath) {
127 return open(Path: DylibPath, Mode: 0);
128}
129
130void EPCGenericDylibManager::lookupSymbolsAsync(
131 tpctypes::DylibHandle H, const SymbolLookupSet &Symbols,
132 DylibManager::SymbolLookupCompleteFn Complete) {
133 lookupAsync(H, Lookup: Symbols, Complete: std::move(Complete));
134}
135
136} // end namespace orc
137} // end namespace llvm
138