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).
78 lines
2.6 KiB
C++
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
|