1fcaf7f86SDimitry Andric //===---------- ExecutorSharedMemoryMapperService.cpp -----------*- C++ -*-===//
2fcaf7f86SDimitry Andric //
3fcaf7f86SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4fcaf7f86SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5fcaf7f86SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6fcaf7f86SDimitry Andric //
7fcaf7f86SDimitry Andric //===----------------------------------------------------------------------===//
8fcaf7f86SDimitry Andric 
9fcaf7f86SDimitry Andric #include "llvm/ExecutionEngine/Orc/TargetProcess/ExecutorSharedMemoryMapperService.h"
10fcaf7f86SDimitry Andric 
11fcaf7f86SDimitry Andric #include "llvm/ExecutionEngine/Orc/Shared/OrcRTBridge.h"
12fcaf7f86SDimitry Andric #include "llvm/Support/Process.h"
13fcaf7f86SDimitry Andric #include "llvm/Support/WindowsError.h"
14fcaf7f86SDimitry Andric 
15fcaf7f86SDimitry Andric #include <sstream>
16fcaf7f86SDimitry Andric 
17fcaf7f86SDimitry Andric #if defined(LLVM_ON_UNIX)
18fcaf7f86SDimitry Andric #include <errno.h>
19fcaf7f86SDimitry Andric #include <fcntl.h>
20fcaf7f86SDimitry Andric #include <sys/mman.h>
21fcaf7f86SDimitry Andric #include <unistd.h>
22fcaf7f86SDimitry Andric #endif
23fcaf7f86SDimitry Andric 
24fcaf7f86SDimitry Andric namespace llvm {
25fcaf7f86SDimitry Andric namespace orc {
26fcaf7f86SDimitry Andric namespace rt_bootstrap {
27fcaf7f86SDimitry Andric 
28bdd1243dSDimitry Andric #if defined(_WIN32)
getWindowsProtectionFlags(MemProt MP)29bdd1243dSDimitry Andric static DWORD getWindowsProtectionFlags(MemProt MP) {
30bdd1243dSDimitry Andric   if (MP == MemProt::Read)
31bdd1243dSDimitry Andric     return PAGE_READONLY;
32bdd1243dSDimitry Andric   if (MP == MemProt::Write ||
33bdd1243dSDimitry Andric       MP == (MemProt::Write | MemProt::Read)) {
34bdd1243dSDimitry Andric     // Note: PAGE_WRITE is not supported by VirtualProtect
35bdd1243dSDimitry Andric     return PAGE_READWRITE;
36bdd1243dSDimitry Andric   }
37bdd1243dSDimitry Andric   if (MP == (MemProt::Read | MemProt::Exec))
38bdd1243dSDimitry Andric     return PAGE_EXECUTE_READ;
39bdd1243dSDimitry Andric   if (MP == (MemProt::Read | MemProt::Write | MemProt::Exec))
40bdd1243dSDimitry Andric     return PAGE_EXECUTE_READWRITE;
41bdd1243dSDimitry Andric   if (MP == MemProt::Exec)
42bdd1243dSDimitry Andric     return PAGE_EXECUTE;
43bdd1243dSDimitry Andric 
44bdd1243dSDimitry Andric   return PAGE_NOACCESS;
45bdd1243dSDimitry Andric }
46bdd1243dSDimitry Andric #endif
47bdd1243dSDimitry Andric 
48fcaf7f86SDimitry Andric Expected<std::pair<ExecutorAddr, std::string>>
reserve(uint64_t Size)49fcaf7f86SDimitry Andric ExecutorSharedMemoryMapperService::reserve(uint64_t Size) {
5061cfbce3SDimitry Andric #if (defined(LLVM_ON_UNIX) && !defined(__ANDROID__)) || defined(_WIN32)
51fcaf7f86SDimitry Andric 
52fcaf7f86SDimitry Andric #if defined(LLVM_ON_UNIX)
53fcaf7f86SDimitry Andric 
54fcaf7f86SDimitry Andric   std::string SharedMemoryName;
55fcaf7f86SDimitry Andric   {
56fcaf7f86SDimitry Andric     std::stringstream SharedMemoryNameStream;
57fcaf7f86SDimitry Andric     SharedMemoryNameStream << "/jitlink_" << sys::Process::getProcessId() << '_'
58fcaf7f86SDimitry Andric                            << (++SharedMemoryCount);
59fcaf7f86SDimitry Andric     SharedMemoryName = SharedMemoryNameStream.str();
60fcaf7f86SDimitry Andric   }
61fcaf7f86SDimitry Andric 
62fcaf7f86SDimitry Andric   int SharedMemoryFile =
63fcaf7f86SDimitry Andric       shm_open(SharedMemoryName.c_str(), O_RDWR | O_CREAT | O_EXCL, 0700);
64fcaf7f86SDimitry Andric   if (SharedMemoryFile < 0)
65fcaf7f86SDimitry Andric     return errorCodeToError(std::error_code(errno, std::generic_category()));
66fcaf7f86SDimitry Andric 
67fcaf7f86SDimitry Andric   // by default size is 0
68fcaf7f86SDimitry Andric   if (ftruncate(SharedMemoryFile, Size) < 0)
69fcaf7f86SDimitry Andric     return errorCodeToError(std::error_code(errno, std::generic_category()));
70fcaf7f86SDimitry Andric 
71fcaf7f86SDimitry Andric   void *Addr = mmap(nullptr, Size, PROT_NONE, MAP_SHARED, SharedMemoryFile, 0);
72fcaf7f86SDimitry Andric   if (Addr == MAP_FAILED)
73fcaf7f86SDimitry Andric     return errorCodeToError(std::error_code(errno, std::generic_category()));
74fcaf7f86SDimitry Andric 
75fcaf7f86SDimitry Andric   close(SharedMemoryFile);
76fcaf7f86SDimitry Andric 
77fcaf7f86SDimitry Andric #elif defined(_WIN32)
78fcaf7f86SDimitry Andric 
79fcaf7f86SDimitry Andric   std::string SharedMemoryName;
80fcaf7f86SDimitry Andric   {
81fcaf7f86SDimitry Andric     std::stringstream SharedMemoryNameStream;
82fcaf7f86SDimitry Andric     SharedMemoryNameStream << "jitlink_" << sys::Process::getProcessId() << '_'
83fcaf7f86SDimitry Andric                            << (++SharedMemoryCount);
84fcaf7f86SDimitry Andric     SharedMemoryName = SharedMemoryNameStream.str();
85fcaf7f86SDimitry Andric   }
86fcaf7f86SDimitry Andric 
87fcaf7f86SDimitry Andric   std::wstring WideSharedMemoryName(SharedMemoryName.begin(),
88fcaf7f86SDimitry Andric                                     SharedMemoryName.end());
89fcaf7f86SDimitry Andric   HANDLE SharedMemoryFile = CreateFileMappingW(
90fcaf7f86SDimitry Andric       INVALID_HANDLE_VALUE, NULL, PAGE_EXECUTE_READWRITE, Size >> 32,
91fcaf7f86SDimitry Andric       Size & 0xffffffff, WideSharedMemoryName.c_str());
92fcaf7f86SDimitry Andric   if (!SharedMemoryFile)
93fcaf7f86SDimitry Andric     return errorCodeToError(mapWindowsError(GetLastError()));
94fcaf7f86SDimitry Andric 
95fcaf7f86SDimitry Andric   void *Addr = MapViewOfFile(SharedMemoryFile,
96fcaf7f86SDimitry Andric                              FILE_MAP_ALL_ACCESS | FILE_MAP_EXECUTE, 0, 0, 0);
97fcaf7f86SDimitry Andric   if (!Addr) {
98fcaf7f86SDimitry Andric     CloseHandle(SharedMemoryFile);
99fcaf7f86SDimitry Andric     return errorCodeToError(mapWindowsError(GetLastError()));
100fcaf7f86SDimitry Andric   }
101fcaf7f86SDimitry Andric 
102fcaf7f86SDimitry Andric #endif
103fcaf7f86SDimitry Andric 
104fcaf7f86SDimitry Andric   {
105fcaf7f86SDimitry Andric     std::lock_guard<std::mutex> Lock(Mutex);
106fcaf7f86SDimitry Andric     Reservations[Addr].Size = Size;
107fcaf7f86SDimitry Andric #if defined(_WIN32)
108fcaf7f86SDimitry Andric     Reservations[Addr].SharedMemoryFile = SharedMemoryFile;
109fcaf7f86SDimitry Andric #endif
110fcaf7f86SDimitry Andric   }
111fcaf7f86SDimitry Andric 
112fcaf7f86SDimitry Andric   return std::make_pair(ExecutorAddr::fromPtr(Addr),
113fcaf7f86SDimitry Andric                         std::move(SharedMemoryName));
114fcaf7f86SDimitry Andric #else
115fcaf7f86SDimitry Andric   return make_error<StringError>(
116fcaf7f86SDimitry Andric       "SharedMemoryMapper is not supported on this platform yet",
117fcaf7f86SDimitry Andric       inconvertibleErrorCode());
118fcaf7f86SDimitry Andric #endif
119fcaf7f86SDimitry Andric }
120fcaf7f86SDimitry Andric 
initialize(ExecutorAddr Reservation,tpctypes::SharedMemoryFinalizeRequest & FR)121fcaf7f86SDimitry Andric Expected<ExecutorAddr> ExecutorSharedMemoryMapperService::initialize(
122fcaf7f86SDimitry Andric     ExecutorAddr Reservation, tpctypes::SharedMemoryFinalizeRequest &FR) {
12361cfbce3SDimitry Andric #if (defined(LLVM_ON_UNIX) && !defined(__ANDROID__)) || defined(_WIN32)
124fcaf7f86SDimitry Andric 
125fcaf7f86SDimitry Andric   ExecutorAddr MinAddr(~0ULL);
126fcaf7f86SDimitry Andric 
127fcaf7f86SDimitry Andric   // Contents are already in place
128fcaf7f86SDimitry Andric   for (auto &Segment : FR.Segments) {
129fcaf7f86SDimitry Andric     if (Segment.Addr < MinAddr)
130fcaf7f86SDimitry Andric       MinAddr = Segment.Addr;
131fcaf7f86SDimitry Andric 
132fcaf7f86SDimitry Andric #if defined(LLVM_ON_UNIX)
133fcaf7f86SDimitry Andric 
134fcaf7f86SDimitry Andric     int NativeProt = 0;
135fe013be4SDimitry Andric     if ((Segment.RAG.Prot & MemProt::Read) == MemProt::Read)
136fcaf7f86SDimitry Andric       NativeProt |= PROT_READ;
137fe013be4SDimitry Andric     if ((Segment.RAG.Prot & MemProt::Write) == MemProt::Write)
138fcaf7f86SDimitry Andric       NativeProt |= PROT_WRITE;
139fe013be4SDimitry Andric     if ((Segment.RAG.Prot & MemProt::Exec) == MemProt::Exec)
140fcaf7f86SDimitry Andric       NativeProt |= PROT_EXEC;
141fcaf7f86SDimitry Andric 
142fcaf7f86SDimitry Andric     if (mprotect(Segment.Addr.toPtr<void *>(), Segment.Size, NativeProt))
143fcaf7f86SDimitry Andric       return errorCodeToError(std::error_code(errno, std::generic_category()));
144fcaf7f86SDimitry Andric 
145fcaf7f86SDimitry Andric #elif defined(_WIN32)
146fcaf7f86SDimitry Andric 
147fe013be4SDimitry Andric     DWORD NativeProt = getWindowsProtectionFlags(Segment.RAG.Prot);
148fcaf7f86SDimitry Andric 
149fcaf7f86SDimitry Andric     if (!VirtualProtect(Segment.Addr.toPtr<void *>(), Segment.Size, NativeProt,
150fcaf7f86SDimitry Andric                         &NativeProt))
151fcaf7f86SDimitry Andric       return errorCodeToError(mapWindowsError(GetLastError()));
152fcaf7f86SDimitry Andric 
153fcaf7f86SDimitry Andric #endif
154fcaf7f86SDimitry Andric 
155fe013be4SDimitry Andric     if ((Segment.RAG.Prot & MemProt::Exec) == MemProt::Exec)
156fcaf7f86SDimitry Andric       sys::Memory::InvalidateInstructionCache(Segment.Addr.toPtr<void *>(),
157fcaf7f86SDimitry Andric                                               Segment.Size);
158fcaf7f86SDimitry Andric   }
159fcaf7f86SDimitry Andric 
160fcaf7f86SDimitry Andric   // Run finalization actions and get deinitlization action list.
161fcaf7f86SDimitry Andric   auto DeinitializeActions = shared::runFinalizeActions(FR.Actions);
162fcaf7f86SDimitry Andric   if (!DeinitializeActions) {
163fcaf7f86SDimitry Andric     return DeinitializeActions.takeError();
164fcaf7f86SDimitry Andric   }
165fcaf7f86SDimitry Andric 
166fcaf7f86SDimitry Andric   {
167fcaf7f86SDimitry Andric     std::lock_guard<std::mutex> Lock(Mutex);
168fcaf7f86SDimitry Andric     Allocations[MinAddr].DeinitializationActions =
169fcaf7f86SDimitry Andric         std::move(*DeinitializeActions);
170fcaf7f86SDimitry Andric     Reservations[Reservation.toPtr<void *>()].Allocations.push_back(MinAddr);
171fcaf7f86SDimitry Andric   }
172fcaf7f86SDimitry Andric 
173fcaf7f86SDimitry Andric   return MinAddr;
174fcaf7f86SDimitry Andric 
175fcaf7f86SDimitry Andric #else
176fcaf7f86SDimitry Andric   return make_error<StringError>(
177fcaf7f86SDimitry Andric       "SharedMemoryMapper is not supported on this platform yet",
178fcaf7f86SDimitry Andric       inconvertibleErrorCode());
179fcaf7f86SDimitry Andric #endif
180fcaf7f86SDimitry Andric }
181fcaf7f86SDimitry Andric 
deinitialize(const std::vector<ExecutorAddr> & Bases)182fcaf7f86SDimitry Andric Error ExecutorSharedMemoryMapperService::deinitialize(
183fcaf7f86SDimitry Andric     const std::vector<ExecutorAddr> &Bases) {
184fcaf7f86SDimitry Andric   Error AllErr = Error::success();
185fcaf7f86SDimitry Andric 
186fcaf7f86SDimitry Andric   {
187fcaf7f86SDimitry Andric     std::lock_guard<std::mutex> Lock(Mutex);
188fcaf7f86SDimitry Andric 
189bdd1243dSDimitry Andric     for (auto Base : llvm::reverse(Bases)) {
190fcaf7f86SDimitry Andric       if (Error Err = shared::runDeallocActions(
191fcaf7f86SDimitry Andric               Allocations[Base].DeinitializationActions)) {
192fcaf7f86SDimitry Andric         AllErr = joinErrors(std::move(AllErr), std::move(Err));
193fcaf7f86SDimitry Andric       }
194fcaf7f86SDimitry Andric 
195bdd1243dSDimitry Andric       // Remove the allocation from the allocation list of its reservation
196bdd1243dSDimitry Andric       for (auto &Reservation : Reservations) {
197*c9157d92SDimitry Andric         auto AllocationIt = llvm::find(Reservation.second.Allocations, Base);
198bdd1243dSDimitry Andric         if (AllocationIt != Reservation.second.Allocations.end()) {
199bdd1243dSDimitry Andric           Reservation.second.Allocations.erase(AllocationIt);
200bdd1243dSDimitry Andric           break;
201bdd1243dSDimitry Andric         }
202bdd1243dSDimitry Andric       }
203bdd1243dSDimitry Andric 
204fcaf7f86SDimitry Andric       Allocations.erase(Base);
205fcaf7f86SDimitry Andric     }
206fcaf7f86SDimitry Andric   }
207fcaf7f86SDimitry Andric 
208fcaf7f86SDimitry Andric   return AllErr;
209fcaf7f86SDimitry Andric }
210fcaf7f86SDimitry Andric 
release(const std::vector<ExecutorAddr> & Bases)211fcaf7f86SDimitry Andric Error ExecutorSharedMemoryMapperService::release(
212fcaf7f86SDimitry Andric     const std::vector<ExecutorAddr> &Bases) {
21361cfbce3SDimitry Andric #if (defined(LLVM_ON_UNIX) && !defined(__ANDROID__)) || defined(_WIN32)
214fcaf7f86SDimitry Andric   Error Err = Error::success();
215fcaf7f86SDimitry Andric 
216fcaf7f86SDimitry Andric   for (auto Base : Bases) {
217fcaf7f86SDimitry Andric     std::vector<ExecutorAddr> AllocAddrs;
218fcaf7f86SDimitry Andric     size_t Size;
219fcaf7f86SDimitry Andric 
220fcaf7f86SDimitry Andric #if defined(_WIN32)
221fcaf7f86SDimitry Andric     HANDLE SharedMemoryFile;
222fcaf7f86SDimitry Andric #endif
223fcaf7f86SDimitry Andric 
224fcaf7f86SDimitry Andric     {
225fcaf7f86SDimitry Andric       std::lock_guard<std::mutex> Lock(Mutex);
226fcaf7f86SDimitry Andric       auto &R = Reservations[Base.toPtr<void *>()];
227fcaf7f86SDimitry Andric       Size = R.Size;
228fcaf7f86SDimitry Andric 
229fcaf7f86SDimitry Andric #if defined(_WIN32)
230fcaf7f86SDimitry Andric       SharedMemoryFile = R.SharedMemoryFile;
231fcaf7f86SDimitry Andric #endif
232fcaf7f86SDimitry Andric 
233fcaf7f86SDimitry Andric       AllocAddrs.swap(R.Allocations);
234fcaf7f86SDimitry Andric     }
235fcaf7f86SDimitry Andric 
236fcaf7f86SDimitry Andric     // deinitialize sub allocations
237fcaf7f86SDimitry Andric     if (Error E = deinitialize(AllocAddrs))
238fcaf7f86SDimitry Andric       Err = joinErrors(std::move(Err), std::move(E));
239fcaf7f86SDimitry Andric 
240fcaf7f86SDimitry Andric #if defined(LLVM_ON_UNIX)
241fcaf7f86SDimitry Andric 
242fcaf7f86SDimitry Andric     if (munmap(Base.toPtr<void *>(), Size) != 0)
243fcaf7f86SDimitry Andric       Err = joinErrors(std::move(Err), errorCodeToError(std::error_code(
244fcaf7f86SDimitry Andric                                            errno, std::generic_category())));
245fcaf7f86SDimitry Andric 
246fcaf7f86SDimitry Andric #elif defined(_WIN32)
24761cfbce3SDimitry Andric     (void)Size;
248fcaf7f86SDimitry Andric 
249fcaf7f86SDimitry Andric     if (!UnmapViewOfFile(Base.toPtr<void *>()))
250fcaf7f86SDimitry Andric       Err = joinErrors(std::move(Err),
251fcaf7f86SDimitry Andric                        errorCodeToError(mapWindowsError(GetLastError())));
252fcaf7f86SDimitry Andric 
253fcaf7f86SDimitry Andric     CloseHandle(SharedMemoryFile);
254fcaf7f86SDimitry Andric 
255fcaf7f86SDimitry Andric #endif
256fcaf7f86SDimitry Andric 
257fcaf7f86SDimitry Andric     std::lock_guard<std::mutex> Lock(Mutex);
258fcaf7f86SDimitry Andric     Reservations.erase(Base.toPtr<void *>());
259fcaf7f86SDimitry Andric   }
260fcaf7f86SDimitry Andric 
261fcaf7f86SDimitry Andric   return Err;
262fcaf7f86SDimitry Andric #else
263fcaf7f86SDimitry Andric   return make_error<StringError>(
264fcaf7f86SDimitry Andric       "SharedMemoryMapper is not supported on this platform yet",
265fcaf7f86SDimitry Andric       inconvertibleErrorCode());
266fcaf7f86SDimitry Andric #endif
267fcaf7f86SDimitry Andric }
268fcaf7f86SDimitry Andric 
shutdown()269fcaf7f86SDimitry Andric Error ExecutorSharedMemoryMapperService::shutdown() {
270bdd1243dSDimitry Andric   if (Reservations.empty())
271fcaf7f86SDimitry Andric     return Error::success();
272bdd1243dSDimitry Andric 
273bdd1243dSDimitry Andric   std::vector<ExecutorAddr> ReservationAddrs;
274bdd1243dSDimitry Andric   ReservationAddrs.reserve(Reservations.size());
275bdd1243dSDimitry Andric   for (const auto &R : Reservations)
276bdd1243dSDimitry Andric     ReservationAddrs.push_back(ExecutorAddr::fromPtr(R.getFirst()));
277bdd1243dSDimitry Andric 
278bdd1243dSDimitry Andric   return release(std::move(ReservationAddrs));
279fcaf7f86SDimitry Andric }
280fcaf7f86SDimitry Andric 
addBootstrapSymbols(StringMap<ExecutorAddr> & M)281fcaf7f86SDimitry Andric void ExecutorSharedMemoryMapperService::addBootstrapSymbols(
282fcaf7f86SDimitry Andric     StringMap<ExecutorAddr> &M) {
283fcaf7f86SDimitry Andric   M[rt::ExecutorSharedMemoryMapperServiceInstanceName] =
284fcaf7f86SDimitry Andric       ExecutorAddr::fromPtr(this);
285fcaf7f86SDimitry Andric   M[rt::ExecutorSharedMemoryMapperServiceReserveWrapperName] =
286fcaf7f86SDimitry Andric       ExecutorAddr::fromPtr(&reserveWrapper);
287fcaf7f86SDimitry Andric   M[rt::ExecutorSharedMemoryMapperServiceInitializeWrapperName] =
288fcaf7f86SDimitry Andric       ExecutorAddr::fromPtr(&initializeWrapper);
289fcaf7f86SDimitry Andric   M[rt::ExecutorSharedMemoryMapperServiceDeinitializeWrapperName] =
290fcaf7f86SDimitry Andric       ExecutorAddr::fromPtr(&deinitializeWrapper);
291fcaf7f86SDimitry Andric   M[rt::ExecutorSharedMemoryMapperServiceReleaseWrapperName] =
292fcaf7f86SDimitry Andric       ExecutorAddr::fromPtr(&releaseWrapper);
293fcaf7f86SDimitry Andric }
294fcaf7f86SDimitry Andric 
295fcaf7f86SDimitry Andric llvm::orc::shared::CWrapperFunctionResult
reserveWrapper(const char * ArgData,size_t ArgSize)296fcaf7f86SDimitry Andric ExecutorSharedMemoryMapperService::reserveWrapper(const char *ArgData,
297fcaf7f86SDimitry Andric                                                   size_t ArgSize) {
298fcaf7f86SDimitry Andric   return shared::WrapperFunction<
299fcaf7f86SDimitry Andric              rt::SPSExecutorSharedMemoryMapperServiceReserveSignature>::
300fcaf7f86SDimitry Andric       handle(ArgData, ArgSize,
301fcaf7f86SDimitry Andric              shared::makeMethodWrapperHandler(
302fcaf7f86SDimitry Andric                  &ExecutorSharedMemoryMapperService::reserve))
303fcaf7f86SDimitry Andric           .release();
304fcaf7f86SDimitry Andric }
305fcaf7f86SDimitry Andric 
306fcaf7f86SDimitry Andric llvm::orc::shared::CWrapperFunctionResult
initializeWrapper(const char * ArgData,size_t ArgSize)307fcaf7f86SDimitry Andric ExecutorSharedMemoryMapperService::initializeWrapper(const char *ArgData,
308fcaf7f86SDimitry Andric                                                      size_t ArgSize) {
309fcaf7f86SDimitry Andric   return shared::WrapperFunction<
310fcaf7f86SDimitry Andric              rt::SPSExecutorSharedMemoryMapperServiceInitializeSignature>::
311fcaf7f86SDimitry Andric       handle(ArgData, ArgSize,
312fcaf7f86SDimitry Andric              shared::makeMethodWrapperHandler(
313fcaf7f86SDimitry Andric                  &ExecutorSharedMemoryMapperService::initialize))
314fcaf7f86SDimitry Andric           .release();
315fcaf7f86SDimitry Andric }
316fcaf7f86SDimitry Andric 
317fcaf7f86SDimitry Andric llvm::orc::shared::CWrapperFunctionResult
deinitializeWrapper(const char * ArgData,size_t ArgSize)318fcaf7f86SDimitry Andric ExecutorSharedMemoryMapperService::deinitializeWrapper(const char *ArgData,
319fcaf7f86SDimitry Andric                                                        size_t ArgSize) {
320fcaf7f86SDimitry Andric   return shared::WrapperFunction<
321fcaf7f86SDimitry Andric              rt::SPSExecutorSharedMemoryMapperServiceDeinitializeSignature>::
322fcaf7f86SDimitry Andric       handle(ArgData, ArgSize,
323fcaf7f86SDimitry Andric              shared::makeMethodWrapperHandler(
324fcaf7f86SDimitry Andric                  &ExecutorSharedMemoryMapperService::deinitialize))
325fcaf7f86SDimitry Andric           .release();
326fcaf7f86SDimitry Andric }
327fcaf7f86SDimitry Andric 
328fcaf7f86SDimitry Andric llvm::orc::shared::CWrapperFunctionResult
releaseWrapper(const char * ArgData,size_t ArgSize)329fcaf7f86SDimitry Andric ExecutorSharedMemoryMapperService::releaseWrapper(const char *ArgData,
330fcaf7f86SDimitry Andric                                                   size_t ArgSize) {
331fcaf7f86SDimitry Andric   return shared::WrapperFunction<
332fcaf7f86SDimitry Andric              rt::SPSExecutorSharedMemoryMapperServiceReleaseSignature>::
333fcaf7f86SDimitry Andric       handle(ArgData, ArgSize,
334fcaf7f86SDimitry Andric              shared::makeMethodWrapperHandler(
335fcaf7f86SDimitry Andric                  &ExecutorSharedMemoryMapperService::release))
336fcaf7f86SDimitry Andric           .release();
337fcaf7f86SDimitry Andric }
338fcaf7f86SDimitry Andric 
339fcaf7f86SDimitry Andric } // namespace rt_bootstrap
340fcaf7f86SDimitry Andric } // end namespace orc
341fcaf7f86SDimitry Andric } // end namespace llvm
342