1 //===---- ExecutorProcessControl.cpp -- Executor process control APIs -----===//
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
7 //===----------------------------------------------------------------------===//
9 #include "llvm/ExecutionEngine/Orc/ExecutorProcessControl.h"
11 #include "llvm/ExecutionEngine/Orc/Core.h"
12 #include "llvm/ExecutionEngine/Orc/TargetProcess/TargetExecutionUtils.h"
13 #include "llvm/Support/FormatVariadic.h"
14 #include "llvm/Support/Host.h"
15 #include "llvm/Support/Process.h"
17 #define DEBUG_TYPE "orc"
22 ExecutorProcessControl::MemoryAccess::~MemoryAccess() {}
24 ExecutorProcessControl::~ExecutorProcessControl() {}
26 SelfExecutorProcessControl::SelfExecutorProcessControl(
27 std::shared_ptr
<SymbolStringPool
> SSP
, Triple TargetTriple
,
28 unsigned PageSize
, std::unique_ptr
<jitlink::JITLinkMemoryManager
> MemMgr
)
29 : ExecutorProcessControl(std::move(SSP
)) {
31 OwnedMemMgr
= std::move(MemMgr
);
33 OwnedMemMgr
= std::make_unique
<jitlink::InProcessMemoryManager
>();
35 this->TargetTriple
= std::move(TargetTriple
);
36 this->PageSize
= PageSize
;
37 this->MemMgr
= OwnedMemMgr
.get();
38 this->MemAccess
= this;
39 this->JDI
= {ExecutorAddress::fromPtr(jitDispatchViaWrapperFunctionManager
),
40 ExecutorAddress::fromPtr(this)};
41 if (this->TargetTriple
.isOSBinFormatMachO())
42 GlobalManglingPrefix
= '_';
45 Expected
<std::unique_ptr
<SelfExecutorProcessControl
>>
46 SelfExecutorProcessControl::Create(
47 std::shared_ptr
<SymbolStringPool
> SSP
,
48 std::unique_ptr
<jitlink::JITLinkMemoryManager
> MemMgr
) {
51 SSP
= std::make_shared
<SymbolStringPool
>();
53 auto PageSize
= sys::Process::getPageSize();
55 return PageSize
.takeError();
57 Triple
TT(sys::getProcessTriple());
59 return std::make_unique
<SelfExecutorProcessControl
>(
60 std::move(SSP
), std::move(TT
), *PageSize
, std::move(MemMgr
));
63 Expected
<tpctypes::DylibHandle
>
64 SelfExecutorProcessControl::loadDylib(const char *DylibPath
) {
66 auto Dylib
= std::make_unique
<sys::DynamicLibrary
>(
67 sys::DynamicLibrary::getPermanentLibrary(DylibPath
, &ErrMsg
));
68 if (!Dylib
->isValid())
69 return make_error
<StringError
>(std::move(ErrMsg
), inconvertibleErrorCode());
70 DynamicLibraries
.push_back(std::move(Dylib
));
71 return pointerToJITTargetAddress(DynamicLibraries
.back().get());
74 Expected
<std::vector
<tpctypes::LookupResult
>>
75 SelfExecutorProcessControl::lookupSymbols(ArrayRef
<LookupRequest
> Request
) {
76 std::vector
<tpctypes::LookupResult
> R
;
78 for (auto &Elem
: Request
) {
79 auto *Dylib
= jitTargetAddressToPointer
<sys::DynamicLibrary
*>(Elem
.Handle
);
80 assert(llvm::any_of(DynamicLibraries
,
81 [=](const std::unique_ptr
<sys::DynamicLibrary
> &DL
) {
82 return DL
.get() == Dylib
;
86 R
.push_back(std::vector
<JITTargetAddress
>());
87 for (auto &KV
: Elem
.Symbols
) {
89 std::string
Tmp((*Sym
).data() + !!GlobalManglingPrefix
,
90 (*Sym
).size() - !!GlobalManglingPrefix
);
91 void *Addr
= Dylib
->getAddressOfSymbol(Tmp
.c_str());
92 if (!Addr
&& KV
.second
== SymbolLookupFlags::RequiredSymbol
) {
93 // FIXME: Collect all failing symbols before erroring out.
94 SymbolNameVector MissingSymbols
;
95 MissingSymbols
.push_back(Sym
);
96 return make_error
<SymbolsNotFound
>(std::move(MissingSymbols
));
98 R
.back().push_back(pointerToJITTargetAddress(Addr
));
106 SelfExecutorProcessControl::runAsMain(JITTargetAddress MainFnAddr
,
107 ArrayRef
<std::string
> Args
) {
108 using MainTy
= int (*)(int, char *[]);
109 return orc::runAsMain(jitTargetAddressToFunction
<MainTy
>(MainFnAddr
), Args
);
112 void SelfExecutorProcessControl::callWrapperAsync(
113 SendResultFunction SendResult
, JITTargetAddress WrapperFnAddr
,
114 ArrayRef
<char> ArgBuffer
) {
116 shared::detail::CWrapperFunctionResult (*)(const char *Data
, size_t Size
);
117 auto *WrapperFn
= jitTargetAddressToFunction
<WrapperFnTy
>(WrapperFnAddr
);
118 SendResult(WrapperFn(ArgBuffer
.data(), ArgBuffer
.size()));
121 Error
SelfExecutorProcessControl::disconnect() { return Error::success(); }
123 void SelfExecutorProcessControl::writeUInt8sAsync(
124 ArrayRef
<tpctypes::UInt8Write
> Ws
, WriteResultFn OnWriteComplete
) {
126 *jitTargetAddressToPointer
<uint8_t *>(W
.Address
) = W
.Value
;
127 OnWriteComplete(Error::success());
130 void SelfExecutorProcessControl::writeUInt16sAsync(
131 ArrayRef
<tpctypes::UInt16Write
> Ws
, WriteResultFn OnWriteComplete
) {
133 *jitTargetAddressToPointer
<uint16_t *>(W
.Address
) = W
.Value
;
134 OnWriteComplete(Error::success());
137 void SelfExecutorProcessControl::writeUInt32sAsync(
138 ArrayRef
<tpctypes::UInt32Write
> Ws
, WriteResultFn OnWriteComplete
) {
140 *jitTargetAddressToPointer
<uint32_t *>(W
.Address
) = W
.Value
;
141 OnWriteComplete(Error::success());
144 void SelfExecutorProcessControl::writeUInt64sAsync(
145 ArrayRef
<tpctypes::UInt64Write
> Ws
, WriteResultFn OnWriteComplete
) {
147 *jitTargetAddressToPointer
<uint64_t *>(W
.Address
) = W
.Value
;
148 OnWriteComplete(Error::success());
151 void SelfExecutorProcessControl::writeBuffersAsync(
152 ArrayRef
<tpctypes::BufferWrite
> Ws
, WriteResultFn OnWriteComplete
) {
154 memcpy(jitTargetAddressToPointer
<char *>(W
.Address
), W
.Buffer
.data(),
156 OnWriteComplete(Error::success());
159 shared::detail::CWrapperFunctionResult
160 SelfExecutorProcessControl::jitDispatchViaWrapperFunctionManager(
161 void *Ctx
, const void *FnTag
, const char *Data
, size_t Size
) {
164 dbgs() << "jit-dispatch call with tag " << FnTag
<< " and " << Size
165 << " byte payload.\n";
168 std::promise
<shared::WrapperFunctionResult
> ResultP
;
169 auto ResultF
= ResultP
.get_future();
170 static_cast<SelfExecutorProcessControl
*>(Ctx
)
171 ->getExecutionSession()
172 .runJITDispatchHandler(
173 [ResultP
= std::move(ResultP
)](
174 shared::WrapperFunctionResult Result
) mutable {
175 ResultP
.set_value(std::move(Result
));
177 pointerToJITTargetAddress(FnTag
), {Data
, Size
});
179 return ResultF
.get().release();
182 } // end namespace orc
183 } // end namespace llvm