[ORC] Use EPC bootstrap symbols to communicate eh-frame registration fn addrs.
By using bootstrap symbols to communicate these addresseses, rather than dlsym lookups, we no longer need them to be exported from the main executable. On ELF, where symbols aren't exported from the main executable by default, this eliminates a common source of missing symbol errors and allows for smaller executables (if exports from the main executable aren't otherwise needed and can be removed).
This commit is contained in:
@@ -33,24 +33,23 @@ public:
|
||||
/// find the registration functions. If it is None then the process dylib
|
||||
/// will be loaded to find the registration functions.
|
||||
static Expected<std::unique_ptr<EPCEHFrameRegistrar>>
|
||||
Create(ExecutionSession &ES,
|
||||
std::optional<ExecutorAddr> RegistrationFunctionsDylib = std::nullopt);
|
||||
Create(ExecutionSession &ES);
|
||||
|
||||
/// Create a EPCEHFrameRegistrar with the given ExecutorProcessControl
|
||||
/// object and registration/deregistration function addresses.
|
||||
EPCEHFrameRegistrar(ExecutionSession &ES,
|
||||
ExecutorAddr RegisterEHFrameWrapperFnAddr,
|
||||
ExecutorAddr DeregisterEHFRameWrapperFnAddr)
|
||||
: ES(ES), RegisterEHFrameWrapperFnAddr(RegisterEHFrameWrapperFnAddr),
|
||||
DeregisterEHFrameWrapperFnAddr(DeregisterEHFRameWrapperFnAddr) {}
|
||||
ExecutorAddr RegisterEHFrameSectionWrapper,
|
||||
ExecutorAddr DeregisterEHFRameSectionWrapper)
|
||||
: ES(ES), RegisterEHFrameSectionWrapper(RegisterEHFrameSectionWrapper),
|
||||
DeregisterEHFrameSectionWrapper(DeregisterEHFRameSectionWrapper) {}
|
||||
|
||||
Error registerEHFrames(ExecutorAddrRange EHFrameSection) override;
|
||||
Error deregisterEHFrames(ExecutorAddrRange EHFrameSection) override;
|
||||
|
||||
private:
|
||||
ExecutionSession &ES;
|
||||
ExecutorAddr RegisterEHFrameWrapperFnAddr;
|
||||
ExecutorAddr DeregisterEHFrameWrapperFnAddr;
|
||||
ExecutorAddr RegisterEHFrameSectionWrapper;
|
||||
ExecutorAddr DeregisterEHFrameSectionWrapper;
|
||||
};
|
||||
|
||||
} // end namespace orc
|
||||
|
||||
@@ -9,67 +9,40 @@
|
||||
#include "llvm/ExecutionEngine/Orc/EPCEHFrameRegistrar.h"
|
||||
|
||||
#include "llvm/ExecutionEngine/Orc/Core.h"
|
||||
#include "llvm/Support/BinaryStreamWriter.h"
|
||||
#include "llvm/ExecutionEngine/Orc/Shared/OrcRTBridge.h"
|
||||
|
||||
using namespace llvm::orc::shared;
|
||||
|
||||
namespace llvm {
|
||||
namespace orc {
|
||||
|
||||
Expected<std::unique_ptr<EPCEHFrameRegistrar>> EPCEHFrameRegistrar::Create(
|
||||
ExecutionSession &ES,
|
||||
std::optional<ExecutorAddr> RegistrationFunctionsDylib) {
|
||||
// FIXME: Proper mangling here -- we really need to decouple linker mangling
|
||||
// from DataLayout.
|
||||
Expected<std::unique_ptr<EPCEHFrameRegistrar>>
|
||||
EPCEHFrameRegistrar::Create(ExecutionSession &ES) {
|
||||
|
||||
// Find the addresses of the registration/deregistration functions in the
|
||||
// executor process.
|
||||
auto &EPC = ES.getExecutorProcessControl();
|
||||
// Lookup addresseses of the registration/deregistration functions in the
|
||||
// bootstrap map.
|
||||
ExecutorAddr RegisterEHFrameSectionWrapper;
|
||||
ExecutorAddr DeregisterEHFrameSectionWrapper;
|
||||
if (auto Err = ES.getExecutorProcessControl().getBootstrapSymbols(
|
||||
{{RegisterEHFrameSectionWrapper,
|
||||
rt::RegisterEHFrameSectionWrapperName},
|
||||
{DeregisterEHFrameSectionWrapper,
|
||||
rt::DeregisterEHFrameSectionWrapperName}}))
|
||||
return Err;
|
||||
|
||||
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, RegisterEHFrameWrapperFnAddr,
|
||||
DeregisterEHFrameWrapperFnAddr);
|
||||
return std::make_unique<EPCEHFrameRegistrar>(
|
||||
ES, RegisterEHFrameSectionWrapper, DeregisterEHFrameSectionWrapper);
|
||||
}
|
||||
|
||||
Error EPCEHFrameRegistrar::registerEHFrames(ExecutorAddrRange EHFrameSection) {
|
||||
return ES.callSPSWrapper<void(SPSExecutorAddrRange)>(
|
||||
RegisterEHFrameWrapperFnAddr, EHFrameSection);
|
||||
RegisterEHFrameSectionWrapper, EHFrameSection);
|
||||
}
|
||||
|
||||
Error EPCEHFrameRegistrar::deregisterEHFrames(
|
||||
ExecutorAddrRange EHFrameSection) {
|
||||
return ES.callSPSWrapper<void(SPSExecutorAddrRange)>(
|
||||
DeregisterEHFrameWrapperFnAddr, EHFrameSection);
|
||||
DeregisterEHFrameSectionWrapper, EHFrameSection);
|
||||
}
|
||||
|
||||
} // end namespace orc
|
||||
|
||||
@@ -9,6 +9,8 @@
|
||||
#include "llvm/ExecutionEngine/Orc/ExecutorProcessControl.h"
|
||||
|
||||
#include "llvm/ExecutionEngine/Orc/Core.h"
|
||||
#include "llvm/ExecutionEngine/Orc/Shared/OrcRTBridge.h"
|
||||
#include "llvm/ExecutionEngine/Orc/TargetProcess/RegisterEHFrames.h"
|
||||
#include "llvm/ExecutionEngine/Orc/TargetProcess/TargetExecutionUtils.h"
|
||||
#include "llvm/Support/FormatVariadic.h"
|
||||
#include "llvm/Support/Process.h"
|
||||
@@ -42,6 +44,11 @@ SelfExecutorProcessControl::SelfExecutorProcessControl(
|
||||
ExecutorAddr::fromPtr(this)};
|
||||
if (this->TargetTriple.isOSBinFormatMachO())
|
||||
GlobalManglingPrefix = '_';
|
||||
|
||||
this->BootstrapSymbols[rt::RegisterEHFrameSectionWrapperName] =
|
||||
ExecutorAddr::fromPtr(&llvm_orc_registerEHFrameSectionWrapper);
|
||||
this->BootstrapSymbols[rt::DeregisterEHFrameSectionWrapperName] =
|
||||
ExecutorAddr::fromPtr(&llvm_orc_deregisterEHFrameSectionWrapper);
|
||||
}
|
||||
|
||||
Expected<std::unique_ptr<SelfExecutorProcessControl>>
|
||||
|
||||
@@ -51,9 +51,9 @@ const char *MemoryWriteBuffersWrapperName =
|
||||
"__llvm_orc_bootstrap_mem_write_buffers_wrapper";
|
||||
|
||||
const char *RegisterEHFrameSectionWrapperName =
|
||||
"__llvm_orc_bootstrap_register_ehframe_section_wrapper";
|
||||
"llvm_orc_registerEHFrameSectionWrapper";
|
||||
const char *DeregisterEHFrameSectionWrapperName =
|
||||
"__llvm_orc_bootstrap_deregister_ehframe_section_wrapper";
|
||||
"llvm_orc_deregisterEHFrameSectionWrapper";
|
||||
|
||||
const char *RunAsMainWrapperName = "__llvm_orc_bootstrap_run_as_main_wrapper";
|
||||
const char *RunAsVoidFunctionWrapperName =
|
||||
|
||||
@@ -8,7 +8,9 @@
|
||||
|
||||
#include "llvm/ExecutionEngine/Orc/TargetProcess/SimpleRemoteEPCServer.h"
|
||||
|
||||
#include "llvm/ExecutionEngine/Orc/Shared/OrcRTBridge.h"
|
||||
#include "llvm/ExecutionEngine/Orc/Shared/TargetProcessControlTypes.h"
|
||||
#include "llvm/ExecutionEngine/Orc/TargetProcess/RegisterEHFrames.h"
|
||||
#include "llvm/Support/FormatVariadic.h"
|
||||
#include "llvm/Support/Process.h"
|
||||
#include "llvm/TargetParser/Host.h"
|
||||
@@ -206,6 +208,10 @@ Error SimpleRemoteEPCServer::sendSetupMessage(
|
||||
"Dispatch function name should not be set");
|
||||
EI.BootstrapSymbols[ExecutorSessionObjectName] = ExecutorAddr::fromPtr(this);
|
||||
EI.BootstrapSymbols[DispatchFnName] = ExecutorAddr::fromPtr(jitDispatchEntry);
|
||||
EI.BootstrapSymbols[rt::RegisterEHFrameSectionWrapperName] =
|
||||
ExecutorAddr::fromPtr(&llvm_orc_registerEHFrameSectionWrapper);
|
||||
EI.BootstrapSymbols[rt::DeregisterEHFrameSectionWrapperName] =
|
||||
ExecutorAddr::fromPtr(&llvm_orc_deregisterEHFrameSectionWrapper);
|
||||
|
||||
using SPSSerialize =
|
||||
shared::SPSArgList<shared::SPSSimpleRemoteEPCExecutorInfo>;
|
||||
|
||||
Reference in New Issue
Block a user