1 //===------------------------ OrcRTBootstrap.cpp --------------------------===// 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 "OrcRTBootstrap.h" 10 11 #include "llvm/ExecutionEngine/Orc/Shared/OrcRTBridge.h" 12 #include "llvm/ExecutionEngine/Orc/Shared/WrapperFunctionUtils.h" 13 #include "llvm/ExecutionEngine/Orc/TargetProcess/TargetExecutionUtils.h" 14 15 #define DEBUG_TYPE "orc" 16 17 using namespace llvm::orc::shared; 18 19 namespace llvm { 20 namespace orc { 21 namespace rt_bootstrap { 22 23 static llvm::orc::shared::detail::CWrapperFunctionResult 24 reserveWrapper(const char *ArgData, size_t ArgSize) { 25 return WrapperFunction<rt::SPSMemoryReserveSignature>::handle( 26 ArgData, ArgSize, 27 [](uint64_t Size) -> Expected<ExecutorAddress> { 28 std::error_code EC; 29 auto MB = sys::Memory::allocateMappedMemory( 30 Size, 0, sys::Memory::MF_READ | sys::Memory::MF_WRITE, EC); 31 if (EC) 32 return errorCodeToError(EC); 33 return ExecutorAddress::fromPtr(MB.base()); 34 }) 35 .release(); 36 } 37 38 static llvm::orc::shared::detail::CWrapperFunctionResult 39 finalizeWrapper(const char *ArgData, size_t ArgSize) { 40 return WrapperFunction<rt::SPSMemoryFinalizeSignature>::handle( 41 ArgData, ArgSize, 42 [](const tpctypes::FinalizeRequest &FR) -> Error { 43 for (auto &Seg : FR) { 44 char *Mem = Seg.Addr.toPtr<char *>(); 45 memcpy(Mem, Seg.Content.data(), Seg.Content.size()); 46 memset(Mem + Seg.Content.size(), 0, 47 Seg.Size - Seg.Content.size()); 48 assert(Seg.Size <= std::numeric_limits<size_t>::max()); 49 if (auto EC = sys::Memory::protectMappedMemory( 50 {Mem, static_cast<size_t>(Seg.Size)}, 51 tpctypes::fromWireProtectionFlags(Seg.Prot))) 52 return errorCodeToError(EC); 53 if (Seg.Prot & tpctypes::WPF_Exec) 54 sys::Memory::InvalidateInstructionCache(Mem, Seg.Size); 55 } 56 return Error::success(); 57 }) 58 .release(); 59 } 60 61 static llvm::orc::shared::detail::CWrapperFunctionResult 62 deallocateWrapper(const char *ArgData, size_t ArgSize) { 63 return WrapperFunction<rt::SPSMemoryDeallocateSignature>::handle( 64 ArgData, ArgSize, 65 [](ExecutorAddress Base, uint64_t Size) -> Error { 66 sys::MemoryBlock MB(Base.toPtr<void *>(), Size); 67 if (auto EC = sys::Memory::releaseMappedMemory(MB)) 68 return errorCodeToError(EC); 69 return Error::success(); 70 }) 71 .release(); 72 } 73 74 template <typename WriteT, typename SPSWriteT> 75 static llvm::orc::shared::detail::CWrapperFunctionResult 76 writeUIntsWrapper(const char *ArgData, size_t ArgSize) { 77 return WrapperFunction<void(SPSSequence<SPSWriteT>)>::handle( 78 ArgData, ArgSize, 79 [](std::vector<WriteT> Ws) { 80 for (auto &W : Ws) 81 *jitTargetAddressToPointer<decltype(W.Value) *>(W.Address) = 82 W.Value; 83 }) 84 .release(); 85 } 86 87 static llvm::orc::shared::detail::CWrapperFunctionResult 88 writeBuffersWrapper(const char *ArgData, size_t ArgSize) { 89 return WrapperFunction<void(SPSSequence<SPSMemoryAccessBufferWrite>)>::handle( 90 ArgData, ArgSize, 91 [](std::vector<tpctypes::BufferWrite> Ws) { 92 for (auto &W : Ws) 93 memcpy(jitTargetAddressToPointer<char *>(W.Address), 94 W.Buffer.data(), W.Buffer.size()); 95 }) 96 .release(); 97 } 98 99 static llvm::orc::shared::detail::CWrapperFunctionResult 100 runAsMainWrapper(const char *ArgData, size_t ArgSize) { 101 return WrapperFunction<rt::SPSRunAsMainSignature>::handle( 102 ArgData, ArgSize, 103 [](ExecutorAddress MainAddr, 104 std::vector<std::string> Args) -> int64_t { 105 return runAsMain(MainAddr.toPtr<int (*)(int, char *[])>(), Args); 106 }) 107 .release(); 108 } 109 110 void addTo(StringMap<ExecutorAddress> &M) { 111 M[rt::MemoryReserveWrapperName] = ExecutorAddress::fromPtr(&reserveWrapper); 112 M[rt::MemoryFinalizeWrapperName] = ExecutorAddress::fromPtr(&finalizeWrapper); 113 M[rt::MemoryDeallocateWrapperName] = 114 ExecutorAddress::fromPtr(&deallocateWrapper); 115 M[rt::MemoryWriteUInt8sWrapperName] = ExecutorAddress::fromPtr( 116 &writeUIntsWrapper<tpctypes::UInt8Write, 117 shared::SPSMemoryAccessUInt8Write>); 118 M[rt::MemoryWriteUInt16sWrapperName] = ExecutorAddress::fromPtr( 119 &writeUIntsWrapper<tpctypes::UInt16Write, 120 shared::SPSMemoryAccessUInt16Write>); 121 M[rt::MemoryWriteUInt32sWrapperName] = ExecutorAddress::fromPtr( 122 &writeUIntsWrapper<tpctypes::UInt32Write, 123 shared::SPSMemoryAccessUInt32Write>); 124 M[rt::MemoryWriteUInt64sWrapperName] = ExecutorAddress::fromPtr( 125 &writeUIntsWrapper<tpctypes::UInt64Write, 126 shared::SPSMemoryAccessUInt64Write>); 127 M[rt::MemoryWriteBuffersWrapperName] = 128 ExecutorAddress::fromPtr(&writeBuffersWrapper); 129 M[rt::RunAsMainWrapperName] = ExecutorAddress::fromPtr(&runAsMainWrapper); 130 } 131 132 } // end namespace rt_bootstrap 133 } // end namespace orc 134 } // end namespace llvm 135