[ORC] Re-apply 98f2bb4461, enable JITEventListeners in OrcV2, with fixes.

Updates the object buffer ownership scheme in jitLinkForOrc and related
functions: Ownership of both the object::ObjectFile and underlying
MemoryBuffer is passed into jitLinkForOrc and passed back to the onEmit
callback once linking is complete. This avoids the use-after-free errors
that were seen in 98f2bb4461.
This commit is contained in:
Lang Hames 2020-03-19 16:14:18 -07:00
parent d6fc61b7e8
commit 39253a50f0
9 changed files with 249 additions and 57 deletions

View File

@ -1,6 +1,7 @@
add_subdirectory(BasicOrcV2CBindings) add_subdirectory(BasicOrcV2CBindings)
add_subdirectory(LLJITDumpObjects) add_subdirectory(LLJITDumpObjects)
add_subdirectory(LLJITWithObjectCache)
add_subdirectory(LLJITWithCustomObjectLinkingLayer) add_subdirectory(LLJITWithCustomObjectLinkingLayer)
add_subdirectory(LLJITWithGDBRegistrationListener)
add_subdirectory(LLJITWithLazyReexports) add_subdirectory(LLJITWithLazyReexports)
add_subdirectory(LLJITWithObjectCache)
add_subdirectory(LLJITWithObjectLinkingLayerPlugin) add_subdirectory(LLJITWithObjectLinkingLayerPlugin)

View File

@ -0,0 +1,16 @@
set(LLVM_LINK_COMPONENTS
Core
IRReader
JITLink
OrcJIT
Support
nativecodegen
)
add_llvm_example(LLJITWithGDBRegistrationListener
LLJITWithGDBRegistrationListener.cpp
)
# We want JIT'd code to be able to link against process symbols like printf
# for this example, so make sure they're exported.
export_executable_symbols(LLJITWithGDBRegistrationListener)

View File

@ -0,0 +1,109 @@
//===--------------- LLJITWithCustomObjectLinkingLayer.cpp ----------------===//
//
// 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
//
//===----------------------------------------------------------------------===//
//
// This file shows how to switch LLJIT to use a custom object linking layer (we
// use ObjectLinkingLayer, which is backed by JITLink, as an example).
//
//===----------------------------------------------------------------------===//
#include "llvm/ADT/StringMap.h"
#include "llvm/ExecutionEngine/JITEventListener.h"
#include "llvm/ExecutionEngine/JITLink/JITLinkMemoryManager.h"
#include "llvm/ExecutionEngine/Orc/ExecutionUtils.h"
#include "llvm/ExecutionEngine/Orc/LLJIT.h"
#include "llvm/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.h"
#include "llvm/ExecutionEngine/SectionMemoryManager.h"
#include "llvm/Support/InitLLVM.h"
#include "llvm/Support/TargetSelect.h"
#include "llvm/Support/raw_ostream.h"
#include "../ExampleModules.h"
using namespace llvm;
using namespace llvm::orc;
ExitOnError ExitOnErr;
static cl::opt<std::string>
EntryPointName("entry", cl::desc("Symbol to call as main entry point"),
cl::init("main"));
static cl::list<std::string> InputFiles(cl::Positional, cl::OneOrMore,
cl::desc("input files"));
static cl::list<std::string> InputArgv("args", cl::Positional,
cl::desc("<program arguments>..."),
cl::ZeroOrMore, cl::PositionalEatsArgs);
int main(int argc, char *argv[]) {
// Initialize LLVM.
InitLLVM X(argc, argv);
InitializeNativeTarget();
InitializeNativeTargetAsmPrinter();
cl::ParseCommandLineOptions(argc, argv, "LLJITWithCustomObjectLinkingLayer");
ExitOnErr.setBanner(std::string(argv[0]) + ": ");
// Detect the host and set code model to small.
auto JTMB = ExitOnErr(JITTargetMachineBuilder::detectHost());
if (!JTMB.getTargetTriple().isOSLinux())
errs()
<< "Warning: This demo may not work for platforms other than Linux.\n";
// Create an LLJIT instance and use a custom object linking layer creator to
// register the GDBRegistrationListener with our RTDyldObjectLinkingLayer.
auto J =
ExitOnErr(LLJITBuilder()
.setJITTargetMachineBuilder(std::move(JTMB))
.setObjectLinkingLayerCreator([&](ExecutionSession &ES,
const Triple &TT) {
auto GetMemMgr = []() {
return std::make_unique<SectionMemoryManager>();
};
auto ObjLinkingLayer =
std::make_unique<RTDyldObjectLinkingLayer>(
ES, std::move(GetMemMgr));
ObjLinkingLayer->registerJITEventListener(
*JITEventListener::createGDBRegistrationListener());
return ObjLinkingLayer;
})
.create());
// Make sure that our process symbols are visible to JIT'd code.
{
MangleAndInterner Mangle(J->getExecutionSession(), J->getDataLayout());
J->getMainJITDylib().addGenerator(
ExitOnErr(orc::DynamicLibrarySearchGenerator::GetForCurrentProcess(
J->getDataLayout().getGlobalPrefix(),
[MainName = Mangle("main")](const orc::SymbolStringPtr &Name) {
return Name != MainName;
})));
}
// Load the input modules.
for (auto &InputFile : InputFiles) {
auto Ctx = std::make_unique<LLVMContext>();
SMDiagnostic Err;
std::unique_ptr<Module> M = parseIRFile(InputFile, Err, *Ctx);
if (!M) {
Err.print(argv[0], errs());
return 1;
}
ExitOnErr(J->addIRModule(ThreadSafeModule(std::move(M), std::move(Ctx))));
}
// Look up the entry point, cast it to a C main function pointer, then use
// runAsMain to call it.
auto EntrySym = ExitOnErr(J->lookup(EntryPointName));
auto EntryFn =
jitTargetAddressToFunction<int (*)(int, char *[])>(EntrySym.getAddress());
return runAsMain(EntryFn, InputArgv, StringRef(InputFiles.front()));
}

View File

@ -16,6 +16,7 @@
#include "llvm/ADT/STLExtras.h" #include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/StringMap.h" #include "llvm/ADT/StringMap.h"
#include "llvm/ADT/StringRef.h" #include "llvm/ADT/StringRef.h"
#include "llvm/ExecutionEngine/JITEventListener.h"
#include "llvm/ExecutionEngine/JITSymbol.h" #include "llvm/ExecutionEngine/JITSymbol.h"
#include "llvm/ExecutionEngine/Orc/Core.h" #include "llvm/ExecutionEngine/Orc/Core.h"
#include "llvm/ExecutionEngine/Orc/Layer.h" #include "llvm/ExecutionEngine/Orc/Layer.h"
@ -115,15 +116,23 @@ public:
return *this; return *this;
} }
/// Register a JITEventListener.
void registerJITEventListener(JITEventListener &L);
/// Unregister a JITEventListener.
void unregisterJITEventListener(JITEventListener &L);
private: private:
Error onObjLoad(VModuleKey K, MaterializationResponsibility &R, Error onObjLoad(VModuleKey K, MaterializationResponsibility &R,
object::ObjectFile &Obj, const object::ObjectFile &Obj,
RuntimeDyld::MemoryManager *MemMgr,
std::unique_ptr<RuntimeDyld::LoadedObjectInfo> LoadedObjInfo, std::unique_ptr<RuntimeDyld::LoadedObjectInfo> LoadedObjInfo,
std::map<StringRef, JITEvaluatedSymbol> Resolved, std::map<StringRef, JITEvaluatedSymbol> Resolved,
std::set<StringRef> &InternalSymbols); std::set<StringRef> &InternalSymbols);
void onObjEmit(VModuleKey K, std::unique_ptr<MemoryBuffer> ObjBuffer, void onObjEmit(VModuleKey K, MaterializationResponsibility &R,
MaterializationResponsibility &R, Error Err); object::OwningBinary<object::ObjectFile> O,
RuntimeDyld::MemoryManager *MemMgr, Error Err);
mutable std::mutex RTDyldLayerMutex; mutable std::mutex RTDyldLayerMutex;
GetMemoryManagerFunction GetMemoryManager; GetMemoryManagerFunction GetMemoryManager;
@ -133,6 +142,10 @@ private:
bool OverrideObjectFlags = false; bool OverrideObjectFlags = false;
bool AutoClaimObjectSymbols = false; bool AutoClaimObjectSymbols = false;
std::vector<std::unique_ptr<RuntimeDyld::MemoryManager>> MemMgrs; std::vector<std::unique_ptr<RuntimeDyld::MemoryManager>> MemMgrs;
std::vector<JITEventListener *> EventListeners;
DenseMap<RuntimeDyld::MemoryManager *,
std::unique_ptr<RuntimeDyld::LoadedObjectInfo>>
LoadedObjInfos;
}; };
class LegacyRTDyldObjectLinkingLayerBase { class LegacyRTDyldObjectLinkingLayerBase {

View File

@ -267,15 +267,16 @@ public:
void finalizeWithMemoryManagerLocking(); void finalizeWithMemoryManagerLocking();
private: private:
friend void friend void jitLinkForORC(
jitLinkForORC(object::ObjectFile &Obj, object::OwningBinary<object::ObjectFile> O,
std::unique_ptr<MemoryBuffer> UnderlyingBuffer, RuntimeDyld::MemoryManager &MemMgr, JITSymbolResolver &Resolver,
RuntimeDyld::MemoryManager &MemMgr, JITSymbolResolver &Resolver, bool ProcessAllSections,
bool ProcessAllSections, unique_function<Error(const object::ObjectFile &Obj,
unique_function<Error(std::unique_ptr<LoadedObjectInfo>, std::unique_ptr<LoadedObjectInfo>,
std::map<StringRef, JITEvaluatedSymbol>)> std::map<StringRef, JITEvaluatedSymbol>)>
OnLoaded, OnLoaded,
unique_function<void(Error)> OnEmitted); unique_function<void(object::OwningBinary<object::ObjectFile> O, Error)>
OnEmitted);
// RuntimeDyldImpl is the actual class. RuntimeDyld is just the public // RuntimeDyldImpl is the actual class. RuntimeDyld is just the public
// interface. // interface.
@ -293,13 +294,15 @@ private:
// instance and uses continuation passing to perform the fix-up and finalize // instance and uses continuation passing to perform the fix-up and finalize
// steps asynchronously. // steps asynchronously.
void jitLinkForORC( void jitLinkForORC(
object::ObjectFile &Obj, std::unique_ptr<MemoryBuffer> UnderlyingBuffer, object::OwningBinary<object::ObjectFile> O,
RuntimeDyld::MemoryManager &MemMgr, JITSymbolResolver &Resolver, RuntimeDyld::MemoryManager &MemMgr, JITSymbolResolver &Resolver,
bool ProcessAllSections, bool ProcessAllSections,
unique_function<Error(std::unique_ptr<RuntimeDyld::LoadedObjectInfo>, unique_function<Error(const object::ObjectFile &Obj,
std::unique_ptr<RuntimeDyld::LoadedObjectInfo>,
std::map<StringRef, JITEvaluatedSymbol>)> std::map<StringRef, JITEvaluatedSymbol>)>
OnLoaded, OnLoaded,
unique_function<void(Error)> OnEmitted); unique_function<void(object::OwningBinary<object::ObjectFile>, Error)>
OnEmitted);
} // end namespace llvm } // end namespace llvm

View File

@ -81,8 +81,12 @@ RTDyldObjectLinkingLayer::RTDyldObjectLinkingLayer(
RTDyldObjectLinkingLayer::~RTDyldObjectLinkingLayer() { RTDyldObjectLinkingLayer::~RTDyldObjectLinkingLayer() {
std::lock_guard<std::mutex> Lock(RTDyldLayerMutex); std::lock_guard<std::mutex> Lock(RTDyldLayerMutex);
for (auto &MemMgr : MemMgrs) for (auto &MemMgr : MemMgrs) {
for (auto *L : EventListeners)
L->notifyFreeingObject(
static_cast<uint64_t>(reinterpret_cast<uintptr_t>(MemMgr.get())));
MemMgr->deregisterEHFrames(); MemMgr->deregisterEHFrames();
}
} }
void RTDyldObjectLinkingLayer::emit(MaterializationResponsibility R, void RTDyldObjectLinkingLayer::emit(MaterializationResponsibility R,
@ -97,13 +101,7 @@ void RTDyldObjectLinkingLayer::emit(MaterializationResponsibility R,
auto &ES = getExecutionSession(); auto &ES = getExecutionSession();
// Create a MemoryBufferRef backed MemoryBuffer (i.e. shallow) copy of the auto Obj = object::ObjectFile::createObjectFile(*O);
// the underlying buffer to pass into RuntimeDyld. This allows us to hold
// ownership of the real underlying buffer and return it to the user once
// the object has been emitted.
auto ObjBuffer = MemoryBuffer::getMemBuffer(O->getMemBufferRef(), false);
auto Obj = object::ObjectFile::createObjectFile(*ObjBuffer);
if (!Obj) { if (!Obj) {
getExecutionSession().reportError(Obj.takeError()); getExecutionSession().reportError(Obj.takeError());
@ -154,20 +152,39 @@ void RTDyldObjectLinkingLayer::emit(MaterializationResponsibility R,
JITDylibSearchOrderResolver Resolver(*SharedR); JITDylibSearchOrderResolver Resolver(*SharedR);
jitLinkForORC( jitLinkForORC(
**Obj, std::move(O), *MemMgr, Resolver, ProcessAllSections, object::OwningBinary<object::ObjectFile>(std::move(*Obj), std::move(O)),
[this, K, SharedR, &Obj, InternalSymbols]( *MemMgr, Resolver, ProcessAllSections,
[this, K, SharedR, MemMgr, InternalSymbols](
const object::ObjectFile &Obj,
std::unique_ptr<RuntimeDyld::LoadedObjectInfo> LoadedObjInfo, std::unique_ptr<RuntimeDyld::LoadedObjectInfo> LoadedObjInfo,
std::map<StringRef, JITEvaluatedSymbol> ResolvedSymbols) { std::map<StringRef, JITEvaluatedSymbol> ResolvedSymbols) {
return onObjLoad(K, *SharedR, **Obj, std::move(LoadedObjInfo), return onObjLoad(K, *SharedR, Obj, MemMgr, std::move(LoadedObjInfo),
ResolvedSymbols, *InternalSymbols); ResolvedSymbols, *InternalSymbols);
}, },
[this, K, SharedR, O = std::move(O)](Error Err) mutable { [this, K, SharedR, MemMgr](object::OwningBinary<object::ObjectFile> Obj,
onObjEmit(K, std::move(O), *SharedR, std::move(Err)); Error Err) mutable {
onObjEmit(K, *SharedR, std::move(Obj), MemMgr, std::move(Err));
}); });
} }
void RTDyldObjectLinkingLayer::registerJITEventListener(JITEventListener &L) {
std::lock_guard<std::mutex> Lock(RTDyldLayerMutex);
assert(llvm::none_of(EventListeners,
[&](JITEventListener *O) { return O == &L; }) &&
"Listener has already been registered");
EventListeners.push_back(&L);
}
void RTDyldObjectLinkingLayer::unregisterJITEventListener(JITEventListener &L) {
std::lock_guard<std::mutex> Lock(RTDyldLayerMutex);
auto I = llvm::find(EventListeners, &L);
assert(I != EventListeners.end() && "Listener not registered");
EventListeners.erase(I);
}
Error RTDyldObjectLinkingLayer::onObjLoad( Error RTDyldObjectLinkingLayer::onObjLoad(
VModuleKey K, MaterializationResponsibility &R, object::ObjectFile &Obj, VModuleKey K, MaterializationResponsibility &R,
const object::ObjectFile &Obj, RuntimeDyld::MemoryManager *MemMgr,
std::unique_ptr<RuntimeDyld::LoadedObjectInfo> LoadedObjInfo, std::unique_ptr<RuntimeDyld::LoadedObjectInfo> LoadedObjInfo,
std::map<StringRef, JITEvaluatedSymbol> Resolved, std::map<StringRef, JITEvaluatedSymbol> Resolved,
std::set<StringRef> &InternalSymbols) { std::set<StringRef> &InternalSymbols) {
@ -252,12 +269,17 @@ Error RTDyldObjectLinkingLayer::onObjLoad(
if (NotifyLoaded) if (NotifyLoaded)
NotifyLoaded(K, Obj, *LoadedObjInfo); NotifyLoaded(K, Obj, *LoadedObjInfo);
std::lock_guard<std::mutex> Lock(RTDyldLayerMutex);
assert(!LoadedObjInfos.count(MemMgr) && "Duplicate loaded info for MemMgr");
LoadedObjInfos[MemMgr] = std::move(LoadedObjInfo);
return Error::success(); return Error::success();
} }
void RTDyldObjectLinkingLayer::onObjEmit( void RTDyldObjectLinkingLayer::onObjEmit(
VModuleKey K, std::unique_ptr<MemoryBuffer> ObjBuffer, VModuleKey K, MaterializationResponsibility &R,
MaterializationResponsibility &R, Error Err) { object::OwningBinary<object::ObjectFile> O,
RuntimeDyld::MemoryManager *MemMgr, Error Err) {
if (Err) { if (Err) {
getExecutionSession().reportError(std::move(Err)); getExecutionSession().reportError(std::move(Err));
R.failMaterialization(); R.failMaterialization();
@ -270,6 +292,22 @@ void RTDyldObjectLinkingLayer::onObjEmit(
return; return;
} }
std::unique_ptr<object::ObjectFile> Obj;
std::unique_ptr<MemoryBuffer> ObjBuffer;
std::tie(Obj, ObjBuffer) = O.takeBinary();
// Run EventListener notifyLoaded callbacks.
{
std::lock_guard<std::mutex> Lock(RTDyldLayerMutex);
auto LOIItr = LoadedObjInfos.find(MemMgr);
assert(LOIItr != LoadedObjInfos.end() && "LoadedObjInfo missing");
for (auto *L : EventListeners)
L->notifyObjectLoaded(
static_cast<uint64_t>(reinterpret_cast<uintptr_t>(MemMgr)), *Obj,
*LOIItr->second);
LoadedObjInfos.erase(MemMgr);
}
if (NotifyEmitted) if (NotifyEmitted)
NotifyEmitted(K, std::move(ObjBuffer)); NotifyEmitted(K, std::move(ObjBuffer));
} }

View File

@ -1190,16 +1190,16 @@ Error RuntimeDyldImpl::resolveExternalSymbols() {
void RuntimeDyldImpl::finalizeAsync( void RuntimeDyldImpl::finalizeAsync(
std::unique_ptr<RuntimeDyldImpl> This, std::unique_ptr<RuntimeDyldImpl> This,
unique_function<void(Error)> OnEmitted, unique_function<void(object::OwningBinary<object::ObjectFile>, Error)>
std::unique_ptr<MemoryBuffer> UnderlyingBuffer) { OnEmitted,
object::OwningBinary<object::ObjectFile> O) {
auto SharedThis = std::shared_ptr<RuntimeDyldImpl>(std::move(This)); auto SharedThis = std::shared_ptr<RuntimeDyldImpl>(std::move(This));
auto PostResolveContinuation = auto PostResolveContinuation =
[SharedThis, OnEmitted = std::move(OnEmitted), [SharedThis, OnEmitted = std::move(OnEmitted), O = std::move(O)](
UnderlyingBuffer = std::move(UnderlyingBuffer)](
Expected<JITSymbolResolver::LookupResult> Result) mutable { Expected<JITSymbolResolver::LookupResult> Result) mutable {
if (!Result) { if (!Result) {
OnEmitted(Result.takeError()); OnEmitted(std::move(O), Result.takeError());
return; return;
} }
@ -1213,10 +1213,11 @@ void RuntimeDyldImpl::finalizeAsync(
SharedThis->registerEHFrames(); SharedThis->registerEHFrames();
std::string ErrMsg; std::string ErrMsg;
if (SharedThis->MemMgr.finalizeMemory(&ErrMsg)) if (SharedThis->MemMgr.finalizeMemory(&ErrMsg))
OnEmitted(make_error<StringError>(std::move(ErrMsg), OnEmitted(std::move(O),
make_error<StringError>(std::move(ErrMsg),
inconvertibleErrorCode())); inconvertibleErrorCode()));
else else
OnEmitted(Error::success()); OnEmitted(std::move(O), Error::success());
}; };
JITSymbolResolver::LookupSet Symbols; JITSymbolResolver::LookupSet Symbols;
@ -1403,32 +1404,35 @@ void RuntimeDyld::deregisterEHFrames() {
// FIXME: Kill this with fire once we have a new JIT linker: this is only here // FIXME: Kill this with fire once we have a new JIT linker: this is only here
// so that we can re-use RuntimeDyld's implementation without twisting the // so that we can re-use RuntimeDyld's implementation without twisting the
// interface any further for ORC's purposes. // interface any further for ORC's purposes.
void jitLinkForORC(object::ObjectFile &Obj, void jitLinkForORC(
std::unique_ptr<MemoryBuffer> UnderlyingBuffer, object::OwningBinary<object::ObjectFile> O,
RuntimeDyld::MemoryManager &MemMgr, RuntimeDyld::MemoryManager &MemMgr, JITSymbolResolver &Resolver,
JITSymbolResolver &Resolver, bool ProcessAllSections, bool ProcessAllSections,
unique_function<Error( unique_function<
std::unique_ptr<RuntimeDyld::LoadedObjectInfo> LoadedObj, Error(const object::ObjectFile &Obj,
std::map<StringRef, JITEvaluatedSymbol>)> std::unique_ptr<RuntimeDyld::LoadedObjectInfo> LoadedObj,
OnLoaded, std::map<StringRef, JITEvaluatedSymbol>)>
unique_function<void(Error)> OnEmitted) { OnLoaded,
unique_function<void(object::OwningBinary<object::ObjectFile>, Error)>
OnEmitted) {
RuntimeDyld RTDyld(MemMgr, Resolver); RuntimeDyld RTDyld(MemMgr, Resolver);
RTDyld.setProcessAllSections(ProcessAllSections); RTDyld.setProcessAllSections(ProcessAllSections);
auto Info = RTDyld.loadObject(Obj); auto Info = RTDyld.loadObject(*O.getBinary());
if (RTDyld.hasError()) { if (RTDyld.hasError()) {
OnEmitted(make_error<StringError>(RTDyld.getErrorString(), OnEmitted(std::move(O), make_error<StringError>(RTDyld.getErrorString(),
inconvertibleErrorCode())); inconvertibleErrorCode()));
return; return;
} }
if (auto Err = OnLoaded(std::move(Info), RTDyld.getSymbolTable())) if (auto Err =
OnEmitted(std::move(Err)); OnLoaded(*O.getBinary(), std::move(Info), RTDyld.getSymbolTable()))
OnEmitted(std::move(O), std::move(Err));
RuntimeDyldImpl::finalizeAsync(std::move(RTDyld.Dyld), std::move(OnEmitted), RuntimeDyldImpl::finalizeAsync(std::move(RTDyld.Dyld), std::move(OnEmitted),
std::move(UnderlyingBuffer)); std::move(O));
} }
} // end namespace llvm } // end namespace llvm

View File

@ -549,9 +549,11 @@ public:
void resolveLocalRelocations(); void resolveLocalRelocations();
static void finalizeAsync(std::unique_ptr<RuntimeDyldImpl> This, static void finalizeAsync(
unique_function<void(Error)> OnEmitted, std::unique_ptr<RuntimeDyldImpl> This,
std::unique_ptr<MemoryBuffer> UnderlyingBuffer); unique_function<void(object::OwningBinary<object::ObjectFile>, Error)>
OnEmitted,
object::OwningBinary<object::ObjectFile> O);
void reassignSectionAddress(unsigned SectionID, uint64_t Addr); void reassignSectionAddress(unsigned SectionID, uint64_t Addr);

View File

@ -30,6 +30,7 @@
#include "llvm/ExecutionEngine/Orc/LLJIT.h" #include "llvm/ExecutionEngine/Orc/LLJIT.h"
#include "llvm/ExecutionEngine/Orc/MachOPlatform.h" #include "llvm/ExecutionEngine/Orc/MachOPlatform.h"
#include "llvm/ExecutionEngine/Orc/OrcRemoteTargetClient.h" #include "llvm/ExecutionEngine/Orc/OrcRemoteTargetClient.h"
#include "llvm/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.h"
#include "llvm/ExecutionEngine/OrcMCJITReplacement.h" #include "llvm/ExecutionEngine/OrcMCJITReplacement.h"
#include "llvm/ExecutionEngine/SectionMemoryManager.h" #include "llvm/ExecutionEngine/SectionMemoryManager.h"
#include "llvm/IR/IRBuilder.h" #include "llvm/IR/IRBuilder.h"
@ -891,6 +892,11 @@ int runOrcLazyJIT(const char *ProgName) {
auto J = ExitOnErr(Builder.create()); auto J = ExitOnErr(Builder.create());
if (TT->isOSBinFormatELF())
static_cast<llvm::orc::RTDyldObjectLinkingLayer &>(J->getObjLinkingLayer())
.registerJITEventListener(
*JITEventListener::createGDBRegistrationListener());
if (PerModuleLazy) if (PerModuleLazy)
J->setPartitionFunction(orc::CompileOnDemandLayer::compileWholeModule); J->setPartitionFunction(orc::CompileOnDemandLayer::compileWholeModule);