Files
clang-p2996/llvm/lib/ExecutionEngine/Orc/TargetProcess/OrcRTBootstrap.cpp
Lang Hames 2c8e784915 [ORC] Add Shared/OrcRTBridge, and TargetProcess/OrcRTBootstrap.
This is a small first step towards reorganization of the ORC libraries:

Declarations for types and function names (as strings) to be found in the
"ORC runtime bootstrap" set are moved into OrcRTBridge.h / OrcRTBridge.cpp.

The current implementation of the "ORC runtime bootstrap" functions is moved
into OrcRTBootstrap.h and OrcRTBootstrap.cpp. It is likely that this code will
eventually be moved into ORT-RT proper (in compiler RT).

The immediate goal of this change is to make these bootstrap functions usable
for clients other than SimpleRemoteEPC/SimpleRemoteEPCServer. The first planned
client is a new RuntimeDyld::MemoryManager that will run over EPC, which will
allow us to remove the old OrcRemoteTarget code.
2021-09-14 10:19:45 +10:00

135 lines
5.5 KiB
C++

//===------------------------ OrcRTBootstrap.cpp --------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#include "OrcRTBootstrap.h"
#include "llvm/ExecutionEngine/Orc/Shared/OrcRTBridge.h"
#include "llvm/ExecutionEngine/Orc/Shared/WrapperFunctionUtils.h"
#include "llvm/ExecutionEngine/Orc/TargetProcess/TargetExecutionUtils.h"
#define DEBUG_TYPE "orc"
using namespace llvm::orc::shared;
namespace llvm {
namespace orc {
namespace rt_bootstrap {
static llvm::orc::shared::detail::CWrapperFunctionResult
reserveWrapper(const char *ArgData, size_t ArgSize) {
return WrapperFunction<rt::SPSMemoryReserveSignature>::handle(
ArgData, ArgSize,
[](uint64_t Size) -> Expected<ExecutorAddress> {
std::error_code EC;
auto MB = sys::Memory::allocateMappedMemory(
Size, 0, sys::Memory::MF_READ | sys::Memory::MF_WRITE, EC);
if (EC)
return errorCodeToError(EC);
return ExecutorAddress::fromPtr(MB.base());
})
.release();
}
static llvm::orc::shared::detail::CWrapperFunctionResult
finalizeWrapper(const char *ArgData, size_t ArgSize) {
return WrapperFunction<rt::SPSMemoryFinalizeSignature>::handle(
ArgData, ArgSize,
[](const tpctypes::FinalizeRequest &FR) -> Error {
for (auto &Seg : FR) {
char *Mem = Seg.Addr.toPtr<char *>();
memcpy(Mem, Seg.Content.data(), Seg.Content.size());
memset(Mem + Seg.Content.size(), 0,
Seg.Size - Seg.Content.size());
assert(Seg.Size <= std::numeric_limits<size_t>::max());
if (auto EC = sys::Memory::protectMappedMemory(
{Mem, static_cast<size_t>(Seg.Size)},
tpctypes::fromWireProtectionFlags(Seg.Prot)))
return errorCodeToError(EC);
if (Seg.Prot & tpctypes::WPF_Exec)
sys::Memory::InvalidateInstructionCache(Mem, Seg.Size);
}
return Error::success();
})
.release();
}
static llvm::orc::shared::detail::CWrapperFunctionResult
deallocateWrapper(const char *ArgData, size_t ArgSize) {
return WrapperFunction<rt::SPSMemoryDeallocateSignature>::handle(
ArgData, ArgSize,
[](ExecutorAddress Base, uint64_t Size) -> Error {
sys::MemoryBlock MB(Base.toPtr<void *>(), Size);
if (auto EC = sys::Memory::releaseMappedMemory(MB))
return errorCodeToError(EC);
return Error::success();
})
.release();
}
template <typename WriteT, typename SPSWriteT>
static llvm::orc::shared::detail::CWrapperFunctionResult
writeUIntsWrapper(const char *ArgData, size_t ArgSize) {
return WrapperFunction<void(SPSSequence<SPSWriteT>)>::handle(
ArgData, ArgSize,
[](std::vector<WriteT> Ws) {
for (auto &W : Ws)
*jitTargetAddressToPointer<decltype(W.Value) *>(W.Address) =
W.Value;
})
.release();
}
static llvm::orc::shared::detail::CWrapperFunctionResult
writeBuffersWrapper(const char *ArgData, size_t ArgSize) {
return WrapperFunction<void(SPSSequence<SPSMemoryAccessBufferWrite>)>::handle(
ArgData, ArgSize,
[](std::vector<tpctypes::BufferWrite> Ws) {
for (auto &W : Ws)
memcpy(jitTargetAddressToPointer<char *>(W.Address),
W.Buffer.data(), W.Buffer.size());
})
.release();
}
static llvm::orc::shared::detail::CWrapperFunctionResult
runAsMainWrapper(const char *ArgData, size_t ArgSize) {
return WrapperFunction<rt::SPSRunAsMainSignature>::handle(
ArgData, ArgSize,
[](ExecutorAddress MainAddr,
std::vector<std::string> Args) -> int64_t {
return runAsMain(MainAddr.toPtr<int (*)(int, char *[])>(), Args);
})
.release();
}
void addTo(StringMap<ExecutorAddress> &M) {
M[rt::MemoryReserveWrapperName] = ExecutorAddress::fromPtr(&reserveWrapper);
M[rt::MemoryFinalizeWrapperName] = ExecutorAddress::fromPtr(&finalizeWrapper);
M[rt::MemoryDeallocateWrapperName] =
ExecutorAddress::fromPtr(&deallocateWrapper);
M[rt::MemoryWriteUInt8sWrapperName] = ExecutorAddress::fromPtr(
&writeUIntsWrapper<tpctypes::UInt8Write,
shared::SPSMemoryAccessUInt8Write>);
M[rt::MemoryWriteUInt16sWrapperName] = ExecutorAddress::fromPtr(
&writeUIntsWrapper<tpctypes::UInt16Write,
shared::SPSMemoryAccessUInt16Write>);
M[rt::MemoryWriteUInt32sWrapperName] = ExecutorAddress::fromPtr(
&writeUIntsWrapper<tpctypes::UInt32Write,
shared::SPSMemoryAccessUInt32Write>);
M[rt::MemoryWriteUInt64sWrapperName] = ExecutorAddress::fromPtr(
&writeUIntsWrapper<tpctypes::UInt64Write,
shared::SPSMemoryAccessUInt64Write>);
M[rt::MemoryWriteBuffersWrapperName] =
ExecutorAddress::fromPtr(&writeBuffersWrapper);
M[rt::RunAsMainWrapperName] = ExecutorAddress::fromPtr(&runAsMainWrapper);
}
} // end namespace rt_bootstrap
} // end namespace orc
} // end namespace llvm