[ORC] Switch to WrapperFunction utility for calls to registration functions.

Addresses FIXMEs in TPC-based EH-frame and debug object registration code by
replacing manual argument serialization with WrapperFunction utility calls.
This commit is contained in:
Lang Hames 2021-06-16 15:12:12 +10:00
parent 062644bb39
commit 834616146b
5 changed files with 38 additions and 54 deletions

View File

@ -372,13 +372,15 @@ public:
if (!ArgBuffer)
return ArgBuffer.takeError();
WrapperFunctionResult ResultBuffer =
Expected<WrapperFunctionResult> ResultBuffer =
Caller(ArgBuffer->data(), ArgBuffer->size());
if (auto ErrMsg = ResultBuffer.getOutOfBandError())
if (!ResultBuffer)
return ResultBuffer.takeError();
if (auto ErrMsg = ResultBuffer->getOutOfBandError())
return make_error<StringError>(ErrMsg, inconvertibleErrorCode());
return detail::ResultDeserializer<SPSRetTagT, RetT>::deserialize(
Result, ResultBuffer.data(), ResultBuffer.size());
Result, ResultBuffer->data(), ResultBuffer->size());
}
/// Handle a call to a wrapper function.

View File

@ -22,6 +22,8 @@
#include <memory>
#include <vector>
using namespace llvm::orc::shared;
namespace llvm {
namespace orc {
@ -36,24 +38,19 @@ public:
/// target process.
class TPCDebugObjectRegistrar : public DebugObjectRegistrar {
public:
using SerializeBlockInfoFn =
std::vector<uint8_t> (*)(sys::MemoryBlock TargetMemBlock);
TPCDebugObjectRegistrar(TargetProcessControl &TPC,
JITTargetAddress RegisterFn,
SerializeBlockInfoFn SerializeBlockInfo)
: TPC(TPC), RegisterFn(RegisterFn),
SerializeBlockInfo(SerializeBlockInfo) {}
JITTargetAddress RegisterFn)
: TPC(TPC), RegisterFn(RegisterFn) {}
Error registerDebugObject(sys::MemoryBlock TargetMem) override {
return TPC.runWrapper(RegisterFn, SerializeBlockInfo(TargetMem))
.takeError();
return WrapperFunction<void(SPSTargetAddress, uint64_t)>::call(
TPCCaller(TPC, RegisterFn), pointerToJITTargetAddress(TargetMem.base()),
static_cast<uint64_t>(TargetMem.allocatedSize()));
}
private:
TargetProcessControl &TPC;
JITTargetAddress RegisterFn;
SerializeBlockInfoFn SerializeBlockInfo;
};
/// Create a TargetProcessControl-based DebugObjectRegistrar that emits debug

View File

@ -163,6 +163,23 @@ protected:
jitlink::JITLinkMemoryManager *MemMgr = nullptr;
};
/// Call a wrapper function via TargetProcessControl::runWrapper.
class TPCCaller {
public:
TPCCaller(TargetProcessControl &TPC, JITTargetAddress WrapperFnAddr)
: TPC(TPC), WrapperFnAddr(WrapperFnAddr) {}
Expected<shared::WrapperFunctionResult> operator()(const char *ArgData,
size_t ArgSize) const {
return TPC.runWrapper(
WrapperFnAddr,
ArrayRef<uint8_t>(reinterpret_cast<const uint8_t *>(ArgData), ArgSize));
}
private:
TargetProcessControl &TPC;
JITTargetAddress WrapperFnAddr;
};
/// A TargetProcessControl implementation targeting the current process.
class SelfTargetProcessControl : public TargetProcessControl,
private TargetProcessControl::MemoryAccess {

View File

@ -15,24 +15,6 @@
namespace llvm {
namespace orc {
// Counterpart for readDebugObjectInfo() in TargetProcess/JITLoaderGDB.cpp
static std::vector<uint8_t>
writeDebugObjectInfo(sys::MemoryBlock TargetMemBlock) {
auto DebugObjAddr = pointerToJITTargetAddress(TargetMemBlock.base());
uint64_t DebugObjSize = TargetMemBlock.allocatedSize();
std::vector<uint8_t> ArgBuffer;
ArgBuffer.resize(sizeof(decltype(DebugObjAddr)) +
sizeof(decltype(DebugObjSize)));
// FIXME: Replace manual serializatio with WrapperFunction utility.
BinaryStreamWriter ArgWriter(ArgBuffer, support::endianness::little);
cantFail(ArgWriter.writeInteger(DebugObjAddr));
cantFail(ArgWriter.writeInteger(DebugObjSize));
return ArgBuffer;
}
Expected<std::unique_ptr<TPCDebugObjectRegistrar>>
createJITLoaderGDBRegistrar(TargetProcessControl &TPC) {
auto ProcessHandle = TPC.loadDylib(nullptr);
@ -55,8 +37,7 @@ createJITLoaderGDBRegistrar(TargetProcessControl &TPC) {
assert((*Result)[0].size() == 1 &&
"Unexpected number of addresses in result");
return std::make_unique<TPCDebugObjectRegistrar>(TPC, (*Result)[0][0],
&writeDebugObjectInfo);
return std::make_unique<TPCDebugObjectRegistrar>(TPC, (*Result)[0][0]);
}
} // namespace orc

View File

@ -9,6 +9,8 @@
#include "llvm/ExecutionEngine/Orc/TPCEHFrameRegistrar.h"
#include "llvm/Support/BinaryStreamWriter.h"
using namespace llvm::orc::shared;
namespace llvm {
namespace orc {
@ -52,32 +54,17 @@ TPCEHFrameRegistrar::Create(TargetProcessControl &TPC) {
Error TPCEHFrameRegistrar::registerEHFrames(JITTargetAddress EHFrameSectionAddr,
size_t EHFrameSectionSize) {
constexpr size_t ArgBufferSize = sizeof(uint64_t) + sizeof(uint64_t);
uint8_t ArgBuffer[ArgBufferSize];
// FIXME: Replace manual serialization with WrapperFunction util call.
BinaryStreamWriter ArgWriter(
MutableArrayRef<uint8_t>(ArgBuffer, ArgBufferSize),
support::endianness::little);
cantFail(ArgWriter.writeInteger(static_cast<uint64_t>(EHFrameSectionAddr)));
cantFail(ArgWriter.writeInteger(static_cast<uint64_t>(EHFrameSectionSize)));
return TPC.runWrapper(RegisterEHFrameWrapperFnAddr, ArgBuffer).takeError();
return WrapperFunction<void(SPSTargetAddress, uint64_t)>::call(
TPCCaller(TPC, RegisterEHFrameWrapperFnAddr), EHFrameSectionAddr,
static_cast<uint64_t>(EHFrameSectionSize));
}
Error TPCEHFrameRegistrar::deregisterEHFrames(
JITTargetAddress EHFrameSectionAddr, size_t EHFrameSectionSize) {
constexpr size_t ArgBufferSize = sizeof(uint64_t) + sizeof(uint64_t);
uint8_t ArgBuffer[ArgBufferSize];
// FIXME: Replace manual serialization with WrapperFunction util call.
BinaryStreamWriter ArgWriter(
MutableArrayRef<uint8_t>(ArgBuffer, ArgBufferSize),
support::endianness::little);
cantFail(ArgWriter.writeInteger(static_cast<uint64_t>(EHFrameSectionAddr)));
cantFail(ArgWriter.writeInteger(static_cast<uint64_t>(EHFrameSectionSize)));
return TPC.runWrapper(DeregisterEHFrameWrapperFnAddr, ArgBuffer).takeError();
return WrapperFunction<void(SPSTargetAddress, uint64_t)>::call(
TPCCaller(TPC, DeregisterEHFrameWrapperFnAddr), EHFrameSectionAddr,
static_cast<uint64_t>(EHFrameSectionSize));
}
} // end namespace orc