[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).
This commit is contained in:
Lang Hames
2022-10-24 13:46:10 -07:00
parent 6613f4aff8
commit c977251ef6
2 changed files with 17 additions and 6 deletions

View File

@@ -28,8 +28,13 @@ public:
/// Create from a ExecutorProcessControl instance alone. This will use
/// the EPC's lookupSymbols method to find the registration/deregistration
/// funciton addresses by name.
///
/// If RegistrationFunctionsDylib is non-None then it will be searched to
/// 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);
Create(ExecutionSession &ES,
Optional<ExecutorAddr> RegistrationFunctionsDylib = None);
/// Create a EPCEHFrameRegistrar with the given ExecutorProcessControl
/// object and registration/deregistration function addresses.

View File

@@ -17,16 +17,21 @@ namespace llvm {
namespace orc {
Expected<std::unique_ptr<EPCEHFrameRegistrar>>
EPCEHFrameRegistrar::Create(ExecutionSession &ES) {
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();
auto ProcessHandle = EPC.loadDylib(nullptr);
if (!ProcessHandle)
return ProcessHandle.takeError();
if (!RegistrationFunctionsDylib) {
if (auto D = EPC.loadDylib(nullptr))
RegistrationFunctionsDylib = *D;
else
return D.takeError();
}
std::string RegisterWrapperName, DeregisterWrapperName;
if (EPC.getTargetTriple().isOSBinFormatMachO()) {
@@ -40,7 +45,8 @@ EPCEHFrameRegistrar::Create(ExecutionSession &ES) {
RegistrationSymbols.add(EPC.intern(RegisterWrapperName));
RegistrationSymbols.add(EPC.intern(DeregisterWrapperName));
auto Result = EPC.lookupSymbols({{*ProcessHandle, RegistrationSymbols}});
auto Result =
EPC.lookupSymbols({{*RegistrationFunctionsDylib, RegistrationSymbols}});
if (!Result)
return Result.takeError();