Files
clang-p2996/llvm/lib/ExecutionEngine/Orc/EPCEHFrameRegistrar.cpp
Lang Hames c977251ef6 [ORC] Allow EPCEHFrameRegistrar clients to specify registration function dylib.
Previously, EPCEHFrameRegistrar always used the
ExecutorProcessControl::loadDylib(nullptr) method to obtain a handle for the
process, but this doesn't work if the registration functions aren't visible in
a standard search of the process (e.g. if the JIT is in a plugin that is loaded
with RTLD_LOCAL).

This patch retains the old behavior by default, but allows clients to supply
their own handle for the library containing the registration functions if they
need to (e.g. to work around limitations like RDLD_LOCAL above, which aren't
expressible within the existing loadDylib / DynamicLibrary APIs).
2022-10-24 13:57:04 -07:00

78 lines
2.6 KiB
C++

//===------ EPCEHFrameRegistrar.cpp - EPC-based eh-frame registration -----===//
//
// 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 "llvm/ExecutionEngine/Orc/EPCEHFrameRegistrar.h"
#include "llvm/ExecutionEngine/Orc/Core.h"
#include "llvm/Support/BinaryStreamWriter.h"
using namespace llvm::orc::shared;
namespace llvm {
namespace orc {
Expected<std::unique_ptr<EPCEHFrameRegistrar>>
EPCEHFrameRegistrar::Create(ExecutionSession &ES,
Optional<ExecutorAddr> RegistrationFunctionsDylib) {
// FIXME: Proper mangling here -- we really need to decouple linker mangling
// from DataLayout.
// Find the addresses of the registration/deregistration functions in the
// executor process.
auto &EPC = ES.getExecutorProcessControl();
if (!RegistrationFunctionsDylib) {
if (auto D = EPC.loadDylib(nullptr))
RegistrationFunctionsDylib = *D;
else
return D.takeError();
}
std::string RegisterWrapperName, DeregisterWrapperName;
if (EPC.getTargetTriple().isOSBinFormatMachO()) {
RegisterWrapperName += '_';
DeregisterWrapperName += '_';
}
RegisterWrapperName += "llvm_orc_registerEHFrameSectionWrapper";
DeregisterWrapperName += "llvm_orc_deregisterEHFrameSectionWrapper";
SymbolLookupSet RegistrationSymbols;
RegistrationSymbols.add(EPC.intern(RegisterWrapperName));
RegistrationSymbols.add(EPC.intern(DeregisterWrapperName));
auto Result =
EPC.lookupSymbols({{*RegistrationFunctionsDylib, RegistrationSymbols}});
if (!Result)
return Result.takeError();
assert(Result->size() == 1 && "Unexpected number of dylibs in result");
assert((*Result)[0].size() == 2 &&
"Unexpected number of addresses in result");
auto RegisterEHFrameWrapperFnAddr = (*Result)[0][0];
auto DeregisterEHFrameWrapperFnAddr = (*Result)[0][1];
return std::make_unique<EPCEHFrameRegistrar>(
ES, ExecutorAddr(RegisterEHFrameWrapperFnAddr),
ExecutorAddr(DeregisterEHFrameWrapperFnAddr));
}
Error EPCEHFrameRegistrar::registerEHFrames(ExecutorAddrRange EHFrameSection) {
return ES.callSPSWrapper<void(SPSExecutorAddrRange)>(
RegisterEHFrameWrapperFnAddr, EHFrameSection);
}
Error EPCEHFrameRegistrar::deregisterEHFrames(
ExecutorAddrRange EHFrameSection) {
return ES.callSPSWrapper<void(SPSExecutorAddrRange)>(
DeregisterEHFrameWrapperFnAddr, EHFrameSection);
}
} // end namespace orc
} // end namespace llvm