199 lines · cpp
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-exception6//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 18using namespace llvm::orc::shared;19 20namespace llvm {21namespace orc {22namespace rt_bootstrap {23 24template <typename WriteT, typename SPSWriteT>25static llvm::orc::shared::CWrapperFunctionResult26writeUIntsWrapper(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 36static llvm::orc::shared::CWrapperFunctionResult37writePointersWrapper(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 48static llvm::orc::shared::CWrapperFunctionResult49writeBuffersWrapper(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 60template <typename ReadT>61static llvm::orc::shared::CWrapperFunctionResult62readUIntsWrapper(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 76static llvm::orc::shared::CWrapperFunctionResult77readPointersWrapper(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 91static llvm::orc::shared::CWrapperFunctionResult92readBuffersWrapper(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 111static llvm::orc::shared::CWrapperFunctionResult112readStringsWrapper(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 126static llvm::orc::shared::CWrapperFunctionResult127runAsMainWrapper(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 137static llvm::orc::shared::CWrapperFunctionResult138runAsVoidFunctionWrapper(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 147static llvm::orc::shared::CWrapperFunctionResult148runAsIntFunctionWrapper(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 158void 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_bootstrap197} // end namespace orc198} // end namespace llvm199