14b4fe385SDimitry Andric //===---------- ExecutorSharedMemoryMapperService.cpp -----------*- C++ -*-===//
24b4fe385SDimitry Andric //
34b4fe385SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
44b4fe385SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
54b4fe385SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
64b4fe385SDimitry Andric //
74b4fe385SDimitry Andric //===----------------------------------------------------------------------===//
84b4fe385SDimitry Andric 
94b4fe385SDimitry Andric #include "llvm/ExecutionEngine/Orc/TargetProcess/ExecutorSharedMemoryMapperService.h"
104b4fe385SDimitry Andric 
114b4fe385SDimitry Andric #include "llvm/ExecutionEngine/Orc/Shared/OrcRTBridge.h"
124b4fe385SDimitry Andric #include "llvm/Support/Process.h"
134b4fe385SDimitry Andric #include "llvm/Support/WindowsError.h"
144b4fe385SDimitry Andric 
154b4fe385SDimitry Andric #include <sstream>
164b4fe385SDimitry Andric 
174b4fe385SDimitry Andric #if defined(LLVM_ON_UNIX)
184b4fe385SDimitry Andric #include <errno.h>
194b4fe385SDimitry Andric #include <fcntl.h>
204b4fe385SDimitry Andric #include <sys/mman.h>
21ac9a064cSDimitry Andric #if defined(__MVS__)
22ac9a064cSDimitry Andric #include "llvm/Support/BLAKE3.h"
23ac9a064cSDimitry Andric #include <sys/shm.h>
24ac9a064cSDimitry Andric #endif
254b4fe385SDimitry Andric #include <unistd.h>
264b4fe385SDimitry Andric #endif
274b4fe385SDimitry Andric 
284b4fe385SDimitry Andric namespace llvm {
294b4fe385SDimitry Andric namespace orc {
304b4fe385SDimitry Andric namespace rt_bootstrap {
314b4fe385SDimitry Andric 
32e3b55780SDimitry Andric #if defined(_WIN32)
getWindowsProtectionFlags(MemProt MP)33e3b55780SDimitry Andric static DWORD getWindowsProtectionFlags(MemProt MP) {
34e3b55780SDimitry Andric   if (MP == MemProt::Read)
35e3b55780SDimitry Andric     return PAGE_READONLY;
36e3b55780SDimitry Andric   if (MP == MemProt::Write ||
37e3b55780SDimitry Andric       MP == (MemProt::Write | MemProt::Read)) {
38e3b55780SDimitry Andric     // Note: PAGE_WRITE is not supported by VirtualProtect
39e3b55780SDimitry Andric     return PAGE_READWRITE;
40e3b55780SDimitry Andric   }
41e3b55780SDimitry Andric   if (MP == (MemProt::Read | MemProt::Exec))
42e3b55780SDimitry Andric     return PAGE_EXECUTE_READ;
43e3b55780SDimitry Andric   if (MP == (MemProt::Read | MemProt::Write | MemProt::Exec))
44e3b55780SDimitry Andric     return PAGE_EXECUTE_READWRITE;
45e3b55780SDimitry Andric   if (MP == MemProt::Exec)
46e3b55780SDimitry Andric     return PAGE_EXECUTE;
47e3b55780SDimitry Andric 
48e3b55780SDimitry Andric   return PAGE_NOACCESS;
49e3b55780SDimitry Andric }
50e3b55780SDimitry Andric #endif
51e3b55780SDimitry Andric 
524b4fe385SDimitry Andric Expected<std::pair<ExecutorAddr, std::string>>
reserve(uint64_t Size)534b4fe385SDimitry Andric ExecutorSharedMemoryMapperService::reserve(uint64_t Size) {
54e3b55780SDimitry Andric #if (defined(LLVM_ON_UNIX) && !defined(__ANDROID__)) || defined(_WIN32)
554b4fe385SDimitry Andric 
564b4fe385SDimitry Andric #if defined(LLVM_ON_UNIX)
574b4fe385SDimitry Andric 
584b4fe385SDimitry Andric   std::string SharedMemoryName;
594b4fe385SDimitry Andric   {
604b4fe385SDimitry Andric     std::stringstream SharedMemoryNameStream;
614b4fe385SDimitry Andric     SharedMemoryNameStream << "/jitlink_" << sys::Process::getProcessId() << '_'
624b4fe385SDimitry Andric                            << (++SharedMemoryCount);
634b4fe385SDimitry Andric     SharedMemoryName = SharedMemoryNameStream.str();
644b4fe385SDimitry Andric   }
654b4fe385SDimitry Andric 
66ac9a064cSDimitry Andric #if defined(__MVS__)
67ac9a064cSDimitry Andric   ArrayRef<uint8_t> Data(
68ac9a064cSDimitry Andric       reinterpret_cast<const uint8_t *>(SharedMemoryName.c_str()),
69ac9a064cSDimitry Andric       SharedMemoryName.size());
70ac9a064cSDimitry Andric   auto HashedName = BLAKE3::hash<sizeof(key_t)>(Data);
71ac9a064cSDimitry Andric   key_t Key = *reinterpret_cast<key_t *>(HashedName.data());
72ac9a064cSDimitry Andric   int SharedMemoryId =
73ac9a064cSDimitry Andric       shmget(Key, Size, IPC_CREAT | IPC_EXCL | __IPC_SHAREAS | 0700);
74ac9a064cSDimitry Andric   if (SharedMemoryId < 0)
75ac9a064cSDimitry Andric     return errorCodeToError(errnoAsErrorCode());
76ac9a064cSDimitry Andric 
77ac9a064cSDimitry Andric   void *Addr = shmat(SharedMemoryId, nullptr, 0);
78ac9a064cSDimitry Andric   if (Addr == reinterpret_cast<void *>(-1))
79ac9a064cSDimitry Andric     return errorCodeToError(errnoAsErrorCode());
80ac9a064cSDimitry Andric #else
814b4fe385SDimitry Andric   int SharedMemoryFile =
824b4fe385SDimitry Andric       shm_open(SharedMemoryName.c_str(), O_RDWR | O_CREAT | O_EXCL, 0700);
834b4fe385SDimitry Andric   if (SharedMemoryFile < 0)
84ac9a064cSDimitry Andric     return errorCodeToError(errnoAsErrorCode());
854b4fe385SDimitry Andric 
864b4fe385SDimitry Andric   // by default size is 0
874b4fe385SDimitry Andric   if (ftruncate(SharedMemoryFile, Size) < 0)
88ac9a064cSDimitry Andric     return errorCodeToError(errnoAsErrorCode());
894b4fe385SDimitry Andric 
904b4fe385SDimitry Andric   void *Addr = mmap(nullptr, Size, PROT_NONE, MAP_SHARED, SharedMemoryFile, 0);
914b4fe385SDimitry Andric   if (Addr == MAP_FAILED)
92ac9a064cSDimitry Andric     return errorCodeToError(errnoAsErrorCode());
934b4fe385SDimitry Andric 
944b4fe385SDimitry Andric   close(SharedMemoryFile);
95ac9a064cSDimitry Andric #endif
964b4fe385SDimitry Andric 
974b4fe385SDimitry Andric #elif defined(_WIN32)
984b4fe385SDimitry Andric 
994b4fe385SDimitry Andric   std::string SharedMemoryName;
1004b4fe385SDimitry Andric   {
1014b4fe385SDimitry Andric     std::stringstream SharedMemoryNameStream;
1024b4fe385SDimitry Andric     SharedMemoryNameStream << "jitlink_" << sys::Process::getProcessId() << '_'
1034b4fe385SDimitry Andric                            << (++SharedMemoryCount);
1044b4fe385SDimitry Andric     SharedMemoryName = SharedMemoryNameStream.str();
1054b4fe385SDimitry Andric   }
1064b4fe385SDimitry Andric 
1074b4fe385SDimitry Andric   std::wstring WideSharedMemoryName(SharedMemoryName.begin(),
1084b4fe385SDimitry Andric                                     SharedMemoryName.end());
1094b4fe385SDimitry Andric   HANDLE SharedMemoryFile = CreateFileMappingW(
1104b4fe385SDimitry Andric       INVALID_HANDLE_VALUE, NULL, PAGE_EXECUTE_READWRITE, Size >> 32,
1114b4fe385SDimitry Andric       Size & 0xffffffff, WideSharedMemoryName.c_str());
1124b4fe385SDimitry Andric   if (!SharedMemoryFile)
1134b4fe385SDimitry Andric     return errorCodeToError(mapWindowsError(GetLastError()));
1144b4fe385SDimitry Andric 
1154b4fe385SDimitry Andric   void *Addr = MapViewOfFile(SharedMemoryFile,
1164b4fe385SDimitry Andric                              FILE_MAP_ALL_ACCESS | FILE_MAP_EXECUTE, 0, 0, 0);
1174b4fe385SDimitry Andric   if (!Addr) {
1184b4fe385SDimitry Andric     CloseHandle(SharedMemoryFile);
1194b4fe385SDimitry Andric     return errorCodeToError(mapWindowsError(GetLastError()));
1204b4fe385SDimitry Andric   }
1214b4fe385SDimitry Andric 
1224b4fe385SDimitry Andric #endif
1234b4fe385SDimitry Andric 
1244b4fe385SDimitry Andric   {
1254b4fe385SDimitry Andric     std::lock_guard<std::mutex> Lock(Mutex);
1264b4fe385SDimitry Andric     Reservations[Addr].Size = Size;
1274b4fe385SDimitry Andric #if defined(_WIN32)
1284b4fe385SDimitry Andric     Reservations[Addr].SharedMemoryFile = SharedMemoryFile;
1294b4fe385SDimitry Andric #endif
1304b4fe385SDimitry Andric   }
1314b4fe385SDimitry Andric 
1324b4fe385SDimitry Andric   return std::make_pair(ExecutorAddr::fromPtr(Addr),
1334b4fe385SDimitry Andric                         std::move(SharedMemoryName));
1344b4fe385SDimitry Andric #else
1354b4fe385SDimitry Andric   return make_error<StringError>(
1364b4fe385SDimitry Andric       "SharedMemoryMapper is not supported on this platform yet",
1374b4fe385SDimitry Andric       inconvertibleErrorCode());
1384b4fe385SDimitry Andric #endif
1394b4fe385SDimitry Andric }
1404b4fe385SDimitry Andric 
initialize(ExecutorAddr Reservation,tpctypes::SharedMemoryFinalizeRequest & FR)1414b4fe385SDimitry Andric Expected<ExecutorAddr> ExecutorSharedMemoryMapperService::initialize(
1424b4fe385SDimitry Andric     ExecutorAddr Reservation, tpctypes::SharedMemoryFinalizeRequest &FR) {
143e3b55780SDimitry Andric #if (defined(LLVM_ON_UNIX) && !defined(__ANDROID__)) || defined(_WIN32)
1444b4fe385SDimitry Andric 
1454b4fe385SDimitry Andric   ExecutorAddr MinAddr(~0ULL);
1464b4fe385SDimitry Andric 
1474b4fe385SDimitry Andric   // Contents are already in place
1484b4fe385SDimitry Andric   for (auto &Segment : FR.Segments) {
1494b4fe385SDimitry Andric     if (Segment.Addr < MinAddr)
1504b4fe385SDimitry Andric       MinAddr = Segment.Addr;
1514b4fe385SDimitry Andric 
1524b4fe385SDimitry Andric #if defined(LLVM_ON_UNIX)
1534b4fe385SDimitry Andric 
154ac9a064cSDimitry Andric #if defined(__MVS__)
155ac9a064cSDimitry Andric       // TODO Is it possible to change the protection level?
156ac9a064cSDimitry Andric #else
1574b4fe385SDimitry Andric     int NativeProt = 0;
1587fa27ce4SDimitry Andric     if ((Segment.RAG.Prot & MemProt::Read) == MemProt::Read)
1594b4fe385SDimitry Andric       NativeProt |= PROT_READ;
1607fa27ce4SDimitry Andric     if ((Segment.RAG.Prot & MemProt::Write) == MemProt::Write)
1614b4fe385SDimitry Andric       NativeProt |= PROT_WRITE;
1627fa27ce4SDimitry Andric     if ((Segment.RAG.Prot & MemProt::Exec) == MemProt::Exec)
1634b4fe385SDimitry Andric       NativeProt |= PROT_EXEC;
1644b4fe385SDimitry Andric 
1654b4fe385SDimitry Andric     if (mprotect(Segment.Addr.toPtr<void *>(), Segment.Size, NativeProt))
166ac9a064cSDimitry Andric       return errorCodeToError(errnoAsErrorCode());
167ac9a064cSDimitry Andric #endif
1684b4fe385SDimitry Andric 
1694b4fe385SDimitry Andric #elif defined(_WIN32)
1704b4fe385SDimitry Andric 
1717fa27ce4SDimitry Andric     DWORD NativeProt = getWindowsProtectionFlags(Segment.RAG.Prot);
1724b4fe385SDimitry Andric 
1734b4fe385SDimitry Andric     if (!VirtualProtect(Segment.Addr.toPtr<void *>(), Segment.Size, NativeProt,
1744b4fe385SDimitry Andric                         &NativeProt))
1754b4fe385SDimitry Andric       return errorCodeToError(mapWindowsError(GetLastError()));
1764b4fe385SDimitry Andric 
1774b4fe385SDimitry Andric #endif
1784b4fe385SDimitry Andric 
1797fa27ce4SDimitry Andric     if ((Segment.RAG.Prot & MemProt::Exec) == MemProt::Exec)
1804b4fe385SDimitry Andric       sys::Memory::InvalidateInstructionCache(Segment.Addr.toPtr<void *>(),
1814b4fe385SDimitry Andric                                               Segment.Size);
1824b4fe385SDimitry Andric   }
1834b4fe385SDimitry Andric 
1844b4fe385SDimitry Andric   // Run finalization actions and get deinitlization action list.
1854b4fe385SDimitry Andric   auto DeinitializeActions = shared::runFinalizeActions(FR.Actions);
1864b4fe385SDimitry Andric   if (!DeinitializeActions) {
1874b4fe385SDimitry Andric     return DeinitializeActions.takeError();
1884b4fe385SDimitry Andric   }
1894b4fe385SDimitry Andric 
1904b4fe385SDimitry Andric   {
1914b4fe385SDimitry Andric     std::lock_guard<std::mutex> Lock(Mutex);
1924b4fe385SDimitry Andric     Allocations[MinAddr].DeinitializationActions =
1934b4fe385SDimitry Andric         std::move(*DeinitializeActions);
1944b4fe385SDimitry Andric     Reservations[Reservation.toPtr<void *>()].Allocations.push_back(MinAddr);
1954b4fe385SDimitry Andric   }
1964b4fe385SDimitry Andric 
1974b4fe385SDimitry Andric   return MinAddr;
1984b4fe385SDimitry Andric 
1994b4fe385SDimitry Andric #else
2004b4fe385SDimitry Andric   return make_error<StringError>(
2014b4fe385SDimitry Andric       "SharedMemoryMapper is not supported on this platform yet",
2024b4fe385SDimitry Andric       inconvertibleErrorCode());
2034b4fe385SDimitry Andric #endif
2044b4fe385SDimitry Andric }
2054b4fe385SDimitry Andric 
deinitialize(const std::vector<ExecutorAddr> & Bases)2064b4fe385SDimitry Andric Error ExecutorSharedMemoryMapperService::deinitialize(
2074b4fe385SDimitry Andric     const std::vector<ExecutorAddr> &Bases) {
2084b4fe385SDimitry Andric   Error AllErr = Error::success();
2094b4fe385SDimitry Andric 
2104b4fe385SDimitry Andric   {
2114b4fe385SDimitry Andric     std::lock_guard<std::mutex> Lock(Mutex);
2124b4fe385SDimitry Andric 
213e3b55780SDimitry Andric     for (auto Base : llvm::reverse(Bases)) {
2144b4fe385SDimitry Andric       if (Error Err = shared::runDeallocActions(
2154b4fe385SDimitry Andric               Allocations[Base].DeinitializationActions)) {
2164b4fe385SDimitry Andric         AllErr = joinErrors(std::move(AllErr), std::move(Err));
2174b4fe385SDimitry Andric       }
2184b4fe385SDimitry Andric 
219e3b55780SDimitry Andric       // Remove the allocation from the allocation list of its reservation
220e3b55780SDimitry Andric       for (auto &Reservation : Reservations) {
221b1c73532SDimitry Andric         auto AllocationIt = llvm::find(Reservation.second.Allocations, Base);
222e3b55780SDimitry Andric         if (AllocationIt != Reservation.second.Allocations.end()) {
223e3b55780SDimitry Andric           Reservation.second.Allocations.erase(AllocationIt);
224e3b55780SDimitry Andric           break;
225e3b55780SDimitry Andric         }
226e3b55780SDimitry Andric       }
227e3b55780SDimitry Andric 
2284b4fe385SDimitry Andric       Allocations.erase(Base);
2294b4fe385SDimitry Andric     }
2304b4fe385SDimitry Andric   }
2314b4fe385SDimitry Andric 
2324b4fe385SDimitry Andric   return AllErr;
2334b4fe385SDimitry Andric }
2344b4fe385SDimitry Andric 
release(const std::vector<ExecutorAddr> & Bases)2354b4fe385SDimitry Andric Error ExecutorSharedMemoryMapperService::release(
2364b4fe385SDimitry Andric     const std::vector<ExecutorAddr> &Bases) {
237e3b55780SDimitry Andric #if (defined(LLVM_ON_UNIX) && !defined(__ANDROID__)) || defined(_WIN32)
2384b4fe385SDimitry Andric   Error Err = Error::success();
2394b4fe385SDimitry Andric 
2404b4fe385SDimitry Andric   for (auto Base : Bases) {
2414b4fe385SDimitry Andric     std::vector<ExecutorAddr> AllocAddrs;
2424b4fe385SDimitry Andric     size_t Size;
2434b4fe385SDimitry Andric 
2444b4fe385SDimitry Andric #if defined(_WIN32)
2454b4fe385SDimitry Andric     HANDLE SharedMemoryFile;
2464b4fe385SDimitry Andric #endif
2474b4fe385SDimitry Andric 
2484b4fe385SDimitry Andric     {
2494b4fe385SDimitry Andric       std::lock_guard<std::mutex> Lock(Mutex);
2504b4fe385SDimitry Andric       auto &R = Reservations[Base.toPtr<void *>()];
2514b4fe385SDimitry Andric       Size = R.Size;
2524b4fe385SDimitry Andric 
2534b4fe385SDimitry Andric #if defined(_WIN32)
2544b4fe385SDimitry Andric       SharedMemoryFile = R.SharedMemoryFile;
2554b4fe385SDimitry Andric #endif
2564b4fe385SDimitry Andric 
2574b4fe385SDimitry Andric       AllocAddrs.swap(R.Allocations);
2584b4fe385SDimitry Andric     }
2594b4fe385SDimitry Andric 
2604b4fe385SDimitry Andric     // deinitialize sub allocations
2614b4fe385SDimitry Andric     if (Error E = deinitialize(AllocAddrs))
2624b4fe385SDimitry Andric       Err = joinErrors(std::move(Err), std::move(E));
2634b4fe385SDimitry Andric 
2644b4fe385SDimitry Andric #if defined(LLVM_ON_UNIX)
2654b4fe385SDimitry Andric 
266ac9a064cSDimitry Andric #if defined(__MVS__)
267ac9a064cSDimitry Andric     (void)Size;
268ac9a064cSDimitry Andric 
269ac9a064cSDimitry Andric     if (shmdt(Base.toPtr<void *>()) < 0)
270ac9a064cSDimitry Andric       Err = joinErrors(std::move(Err), errorCodeToError(errnoAsErrorCode()));
271ac9a064cSDimitry Andric #else
2724b4fe385SDimitry Andric     if (munmap(Base.toPtr<void *>(), Size) != 0)
273ac9a064cSDimitry Andric       Err = joinErrors(std::move(Err), errorCodeToError(errnoAsErrorCode()));
274ac9a064cSDimitry Andric #endif
2754b4fe385SDimitry Andric 
2764b4fe385SDimitry Andric #elif defined(_WIN32)
277e3b55780SDimitry Andric     (void)Size;
2784b4fe385SDimitry Andric 
2794b4fe385SDimitry Andric     if (!UnmapViewOfFile(Base.toPtr<void *>()))
2804b4fe385SDimitry Andric       Err = joinErrors(std::move(Err),
2814b4fe385SDimitry Andric                        errorCodeToError(mapWindowsError(GetLastError())));
2824b4fe385SDimitry Andric 
2834b4fe385SDimitry Andric     CloseHandle(SharedMemoryFile);
2844b4fe385SDimitry Andric 
2854b4fe385SDimitry Andric #endif
2864b4fe385SDimitry Andric 
2874b4fe385SDimitry Andric     std::lock_guard<std::mutex> Lock(Mutex);
2884b4fe385SDimitry Andric     Reservations.erase(Base.toPtr<void *>());
2894b4fe385SDimitry Andric   }
2904b4fe385SDimitry Andric 
2914b4fe385SDimitry Andric   return Err;
2924b4fe385SDimitry Andric #else
2934b4fe385SDimitry Andric   return make_error<StringError>(
2944b4fe385SDimitry Andric       "SharedMemoryMapper is not supported on this platform yet",
2954b4fe385SDimitry Andric       inconvertibleErrorCode());
2964b4fe385SDimitry Andric #endif
2974b4fe385SDimitry Andric }
2984b4fe385SDimitry Andric 
shutdown()2994b4fe385SDimitry Andric Error ExecutorSharedMemoryMapperService::shutdown() {
300e3b55780SDimitry Andric   if (Reservations.empty())
3014b4fe385SDimitry Andric     return Error::success();
302e3b55780SDimitry Andric 
303e3b55780SDimitry Andric   std::vector<ExecutorAddr> ReservationAddrs;
304e3b55780SDimitry Andric   ReservationAddrs.reserve(Reservations.size());
305e3b55780SDimitry Andric   for (const auto &R : Reservations)
306e3b55780SDimitry Andric     ReservationAddrs.push_back(ExecutorAddr::fromPtr(R.getFirst()));
307e3b55780SDimitry Andric 
308e3b55780SDimitry Andric   return release(std::move(ReservationAddrs));
3094b4fe385SDimitry Andric }
3104b4fe385SDimitry Andric 
addBootstrapSymbols(StringMap<ExecutorAddr> & M)3114b4fe385SDimitry Andric void ExecutorSharedMemoryMapperService::addBootstrapSymbols(
3124b4fe385SDimitry Andric     StringMap<ExecutorAddr> &M) {
3134b4fe385SDimitry Andric   M[rt::ExecutorSharedMemoryMapperServiceInstanceName] =
3144b4fe385SDimitry Andric       ExecutorAddr::fromPtr(this);
3154b4fe385SDimitry Andric   M[rt::ExecutorSharedMemoryMapperServiceReserveWrapperName] =
3164b4fe385SDimitry Andric       ExecutorAddr::fromPtr(&reserveWrapper);
3174b4fe385SDimitry Andric   M[rt::ExecutorSharedMemoryMapperServiceInitializeWrapperName] =
3184b4fe385SDimitry Andric       ExecutorAddr::fromPtr(&initializeWrapper);
3194b4fe385SDimitry Andric   M[rt::ExecutorSharedMemoryMapperServiceDeinitializeWrapperName] =
3204b4fe385SDimitry Andric       ExecutorAddr::fromPtr(&deinitializeWrapper);
3214b4fe385SDimitry Andric   M[rt::ExecutorSharedMemoryMapperServiceReleaseWrapperName] =
3224b4fe385SDimitry Andric       ExecutorAddr::fromPtr(&releaseWrapper);
3234b4fe385SDimitry Andric }
3244b4fe385SDimitry Andric 
3254b4fe385SDimitry Andric llvm::orc::shared::CWrapperFunctionResult
reserveWrapper(const char * ArgData,size_t ArgSize)3264b4fe385SDimitry Andric ExecutorSharedMemoryMapperService::reserveWrapper(const char *ArgData,
3274b4fe385SDimitry Andric                                                   size_t ArgSize) {
3284b4fe385SDimitry Andric   return shared::WrapperFunction<
3294b4fe385SDimitry Andric              rt::SPSExecutorSharedMemoryMapperServiceReserveSignature>::
3304b4fe385SDimitry Andric       handle(ArgData, ArgSize,
3314b4fe385SDimitry Andric              shared::makeMethodWrapperHandler(
3324b4fe385SDimitry Andric                  &ExecutorSharedMemoryMapperService::reserve))
3334b4fe385SDimitry Andric           .release();
3344b4fe385SDimitry Andric }
3354b4fe385SDimitry Andric 
3364b4fe385SDimitry Andric llvm::orc::shared::CWrapperFunctionResult
initializeWrapper(const char * ArgData,size_t ArgSize)3374b4fe385SDimitry Andric ExecutorSharedMemoryMapperService::initializeWrapper(const char *ArgData,
3384b4fe385SDimitry Andric                                                      size_t ArgSize) {
3394b4fe385SDimitry Andric   return shared::WrapperFunction<
3404b4fe385SDimitry Andric              rt::SPSExecutorSharedMemoryMapperServiceInitializeSignature>::
3414b4fe385SDimitry Andric       handle(ArgData, ArgSize,
3424b4fe385SDimitry Andric              shared::makeMethodWrapperHandler(
3434b4fe385SDimitry Andric                  &ExecutorSharedMemoryMapperService::initialize))
3444b4fe385SDimitry Andric           .release();
3454b4fe385SDimitry Andric }
3464b4fe385SDimitry Andric 
3474b4fe385SDimitry Andric llvm::orc::shared::CWrapperFunctionResult
deinitializeWrapper(const char * ArgData,size_t ArgSize)3484b4fe385SDimitry Andric ExecutorSharedMemoryMapperService::deinitializeWrapper(const char *ArgData,
3494b4fe385SDimitry Andric                                                        size_t ArgSize) {
3504b4fe385SDimitry Andric   return shared::WrapperFunction<
3514b4fe385SDimitry Andric              rt::SPSExecutorSharedMemoryMapperServiceDeinitializeSignature>::
3524b4fe385SDimitry Andric       handle(ArgData, ArgSize,
3534b4fe385SDimitry Andric              shared::makeMethodWrapperHandler(
3544b4fe385SDimitry Andric                  &ExecutorSharedMemoryMapperService::deinitialize))
3554b4fe385SDimitry Andric           .release();
3564b4fe385SDimitry Andric }
3574b4fe385SDimitry Andric 
3584b4fe385SDimitry Andric llvm::orc::shared::CWrapperFunctionResult
releaseWrapper(const char * ArgData,size_t ArgSize)3594b4fe385SDimitry Andric ExecutorSharedMemoryMapperService::releaseWrapper(const char *ArgData,
3604b4fe385SDimitry Andric                                                   size_t ArgSize) {
3614b4fe385SDimitry Andric   return shared::WrapperFunction<
3624b4fe385SDimitry Andric              rt::SPSExecutorSharedMemoryMapperServiceReleaseSignature>::
3634b4fe385SDimitry Andric       handle(ArgData, ArgSize,
3644b4fe385SDimitry Andric              shared::makeMethodWrapperHandler(
3654b4fe385SDimitry Andric                  &ExecutorSharedMemoryMapperService::release))
3664b4fe385SDimitry Andric           .release();
3674b4fe385SDimitry Andric }
3684b4fe385SDimitry Andric 
3694b4fe385SDimitry Andric } // namespace rt_bootstrap
3704b4fe385SDimitry Andric } // end namespace orc
3714b4fe385SDimitry Andric } // end namespace llvm
372