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/RegisterEHFrames.h" 14 #include "llvm/ExecutionEngine/Orc/TargetProcess/TargetExecutionUtils.h" 15 16 #define DEBUG_TYPE "orc" 17 18 using namespace llvm::orc::shared; 19 20 namespace llvm { 21 namespace orc { 22 namespace rt_bootstrap { 23 24 template <typename WriteT, typename SPSWriteT> 25 static llvm::orc::shared::CWrapperFunctionResult 26 writeUIntsWrapper(const char *ArgData, size_t ArgSize) { 27 return WrapperFunction<void(SPSSequence<SPSWriteT>)>::handle( 28 ArgData, ArgSize, 29 [](std::vector<WriteT> Ws) { 30 for (auto &W : Ws) 31 *W.Addr.template toPtr<decltype(W.Value) *>() = W.Value; 32 }) 33 .release(); 34 } 35 36 static llvm::orc::shared::CWrapperFunctionResult 37 writePointersWrapper(const char *ArgData, size_t ArgSize) { 38 return WrapperFunction<void(SPSSequence<SPSMemoryAccessPointerWrite>)>:: 39 handle(ArgData, ArgSize, 40 [](std::vector<tpctypes::PointerWrite> Ws) { 41 for (auto &W : Ws) 42 *W.Addr.template toPtr<void **>() = 43 W.Value.template toPtr<void *>(); 44 }) 45 .release(); 46 } 47 48 static llvm::orc::shared::CWrapperFunctionResult 49 writeBuffersWrapper(const char *ArgData, size_t ArgSize) { 50 return WrapperFunction<void(SPSSequence<SPSMemoryAccessBufferWrite>)>::handle( 51 ArgData, ArgSize, 52 [](std::vector<tpctypes::BufferWrite> Ws) { 53 for (auto &W : Ws) 54 memcpy(W.Addr.template toPtr<char *>(), W.Buffer.data(), 55 W.Buffer.size()); 56 }) 57 .release(); 58 } 59 60 template <typename ReadT> 61 static llvm::orc::shared::CWrapperFunctionResult 62 readUIntsWrapper(const char *ArgData, size_t ArgSize) { 63 using SPSSig = SPSSequence<ReadT>(SPSSequence<SPSExecutorAddr>); 64 return WrapperFunction<SPSSig>::handle(ArgData, ArgSize, 65 [](std::vector<ExecutorAddr> Rs) { 66 std::vector<ReadT> Result; 67 Result.reserve(Rs.size()); 68 for (auto &R : Rs) 69 Result.push_back( 70 *R.toPtr<ReadT *>()); 71 return Result; 72 }) 73 .release(); 74 } 75 76 static llvm::orc::shared::CWrapperFunctionResult 77 readPointersWrapper(const char *ArgData, size_t ArgSize) { 78 using SPSSig = SPSSequence<SPSExecutorAddr>(SPSSequence<SPSExecutorAddr>); 79 return WrapperFunction<SPSSig>::handle( 80 ArgData, ArgSize, 81 [](std::vector<ExecutorAddr> Rs) { 82 std::vector<ExecutorAddr> Result; 83 Result.reserve(Rs.size()); 84 for (auto &R : Rs) 85 Result.push_back(ExecutorAddr::fromPtr(*R.toPtr<void **>())); 86 return Result; 87 }) 88 .release(); 89 } 90 91 static llvm::orc::shared::CWrapperFunctionResult 92 readBuffersWrapper(const char *ArgData, size_t ArgSize) { 93 using SPSSig = 94 SPSSequence<SPSSequence<uint8_t>>(SPSSequence<SPSExecutorAddrRange>); 95 return WrapperFunction<SPSSig>::handle( 96 ArgData, ArgSize, 97 [](std::vector<ExecutorAddrRange> Rs) { 98 std::vector<std::vector<uint8_t>> Result; 99 Result.reserve(Rs.size()); 100 for (auto &R : Rs) { 101 Result.push_back({}); 102 Result.back().resize(R.size()); 103 memcpy(reinterpret_cast<char *>(Result.back().data()), 104 R.Start.toPtr<char *>(), R.size()); 105 } 106 return Result; 107 }) 108 .release(); 109 } 110 111 static llvm::orc::shared::CWrapperFunctionResult 112 readStringsWrapper(const char *ArgData, size_t ArgSize) { 113 using SPSSig = SPSSequence<SPSString>(SPSSequence<SPSExecutorAddr>); 114 return WrapperFunction<SPSSig>::handle(ArgData, ArgSize, 115 [](std::vector<ExecutorAddr> Rs) { 116 std::vector<std::string> Result; 117 Result.reserve(Rs.size()); 118 for (auto &R : Rs) 119 Result.push_back( 120 R.toPtr<char *>()); 121 return Result; 122 }) 123 .release(); 124 } 125 126 static llvm::orc::shared::CWrapperFunctionResult 127 runAsMainWrapper(const char *ArgData, size_t ArgSize) { 128 return WrapperFunction<rt::SPSRunAsMainSignature>::handle( 129 ArgData, ArgSize, 130 [](ExecutorAddr MainAddr, 131 std::vector<std::string> Args) -> int64_t { 132 return runAsMain(MainAddr.toPtr<int (*)(int, char *[])>(), Args); 133 }) 134 .release(); 135 } 136 137 static llvm::orc::shared::CWrapperFunctionResult 138 runAsVoidFunctionWrapper(const char *ArgData, size_t ArgSize) { 139 return WrapperFunction<rt::SPSRunAsVoidFunctionSignature>::handle( 140 ArgData, ArgSize, 141 [](ExecutorAddr MainAddr) -> int32_t { 142 return runAsVoidFunction(MainAddr.toPtr<int32_t (*)(void)>()); 143 }) 144 .release(); 145 } 146 147 static llvm::orc::shared::CWrapperFunctionResult 148 runAsIntFunctionWrapper(const char *ArgData, size_t ArgSize) { 149 return WrapperFunction<rt::SPSRunAsIntFunctionSignature>::handle( 150 ArgData, ArgSize, 151 [](ExecutorAddr MainAddr, int32_t Arg) -> int32_t { 152 return runAsIntFunction(MainAddr.toPtr<int32_t (*)(int32_t)>(), 153 Arg); 154 }) 155 .release(); 156 } 157 158 void addTo(StringMap<ExecutorAddr> &M) { 159 M[rt::MemoryWriteUInt8sWrapperName] = ExecutorAddr::fromPtr( 160 &writeUIntsWrapper<tpctypes::UInt8Write, 161 shared::SPSMemoryAccessUInt8Write>); 162 M[rt::MemoryWriteUInt16sWrapperName] = ExecutorAddr::fromPtr( 163 &writeUIntsWrapper<tpctypes::UInt16Write, 164 shared::SPSMemoryAccessUInt16Write>); 165 M[rt::MemoryWriteUInt32sWrapperName] = ExecutorAddr::fromPtr( 166 &writeUIntsWrapper<tpctypes::UInt32Write, 167 shared::SPSMemoryAccessUInt32Write>); 168 M[rt::MemoryWriteUInt64sWrapperName] = ExecutorAddr::fromPtr( 169 &writeUIntsWrapper<tpctypes::UInt64Write, 170 shared::SPSMemoryAccessUInt64Write>); 171 M[rt::MemoryWritePointersWrapperName] = 172 ExecutorAddr::fromPtr(&writePointersWrapper); 173 M[rt::MemoryWriteBuffersWrapperName] = 174 ExecutorAddr::fromPtr(&writeBuffersWrapper); 175 M[rt::MemoryReadUInt8sWrapperName] = 176 ExecutorAddr::fromPtr(&readUIntsWrapper<uint8_t>); 177 M[rt::MemoryReadUInt16sWrapperName] = 178 ExecutorAddr::fromPtr(&readUIntsWrapper<uint16_t>); 179 M[rt::MemoryReadUInt32sWrapperName] = 180 ExecutorAddr::fromPtr(&readUIntsWrapper<uint32_t>); 181 M[rt::MemoryReadUInt64sWrapperName] = 182 ExecutorAddr::fromPtr(&readUIntsWrapper<uint64_t>); 183 M[rt::MemoryReadPointersWrapperName] = 184 ExecutorAddr::fromPtr(&readPointersWrapper); 185 M[rt::MemoryReadBuffersWrapperName] = 186 ExecutorAddr::fromPtr(&readBuffersWrapper); 187 M[rt::MemoryReadStringsWrapperName] = 188 ExecutorAddr::fromPtr(&readStringsWrapper); 189 M[rt::RunAsMainWrapperName] = ExecutorAddr::fromPtr(&runAsMainWrapper); 190 M[rt::RunAsVoidFunctionWrapperName] = 191 ExecutorAddr::fromPtr(&runAsVoidFunctionWrapper); 192 M[rt::RunAsIntFunctionWrapperName] = 193 ExecutorAddr::fromPtr(&runAsIntFunctionWrapper); 194 } 195 196 } // end namespace rt_bootstrap 197 } // end namespace orc 198 } // end namespace llvm 199