#include "llvm/Analysis/Passes.h"
#include "llvm/ExecutionEngine/Orc/CompileUtils.h"
#include "llvm/ExecutionEngine/Orc/IRCompileLayer.h"
+#include "llvm/ExecutionEngine/Orc/LambdaResolver.h"
#include "llvm/ExecutionEngine/Orc/LazyEmittingLayer.h"
#include "llvm/ExecutionEngine/Orc/ObjectLinkingLayer.h"
#include "llvm/ExecutionEngine/Orc/OrcTargetSupport.h"
KaleidoscopeJIT(SessionContext &Session)
: Session(Session),
Mang(Session.getTarget().getDataLayout()),
- ObjectLayer(
- [](){ return llvm::make_unique<SectionMemoryManager>(); }),
CompileLayer(ObjectLayer, SimpleCompiler(Session.getTarget())),
LazyEmitLayer(CompileLayer),
- CompileCallbacks(LazyEmitLayer, Session.getLLVMContext(),
+ CompileCallbacks(LazyEmitLayer, CCMgrMemMgr, Session.getLLVMContext(),
reinterpret_cast<uintptr_t>(EarthShatteringKaboom),
64) {}
// We need a memory manager to allocate memory and resolve symbols for this
// new module. Create one that resolves symbols by looking back into the
// JIT.
- auto MM = createLookasideRTDyldMM<SectionMemoryManager>(
- [&](const std::string &Name) {
- // First try to find 'Name' within the JIT.
- if (auto Symbol = findSymbol(Name))
- return Symbol.getAddress();
-
- // If we don't already have a definition of 'Name' then search
- // the ASTs.
- return searchFunctionASTs(Name);
- },
- [](const std::string &S) { return 0; } );
+ auto Resolver = createLambdaResolver(
+ [&](const std::string &Name) {
+ // First try to find 'Name' within the JIT.
+ if (auto Symbol = findSymbol(Name))
+ return RuntimeDyld::SymbolInfo(Symbol.getAddress(),
+ Symbol.getFlags());
+
+ // If we don't already have a definition of 'Name' then search
+ // the ASTs.
+ return searchFunctionASTs(Name);
+ },
+ [](const std::string &S) { return nullptr; } );
return LazyEmitLayer.addModuleSet(singletonSet(std::move(M)),
- std::move(MM));
+ make_unique<SectionMemoryManager>(),
+ std::move(Resolver));
}
void removeModule(ModuleHandleT H) { LazyEmitLayer.removeModuleSet(H); }
// This method searches the FunctionDefs map for a definition of 'Name'. If it
// finds one it generates a stub for it and returns the address of the stub.
- TargetAddress searchFunctionASTs(const std::string &Name) {
+ RuntimeDyld::SymbolInfo searchFunctionASTs(const std::string &Name) {
auto DefI = FunctionDefs.find(Name);
if (DefI == FunctionDefs.end())
return 0;
// IRGen the AST, add it to the JIT, and return the address for it.
auto H = irGenStub(std::move(FnAST));
- return findSymbolIn(H, Name).getAddress();
+ auto Sym = findSymbolIn(H, Name);
+ return RuntimeDyld::SymbolInfo(Sym.getAddress(), Sym.getFlags());
}
// This method will take the AST for a function definition and IR-gen a stub
// compile and update actions for the callback, and get a pointer to
// the jit trampoline that we need to call to trigger those actions.
auto CallbackInfo =
- CompileCallbacks.getCompileCallback(*F->getFunctionType());
+ CompileCallbacks.getCompileCallback(F->getContext());
// Step 3) Create a stub that will indirectly call the body of this
// function once it is compiled. Initially, set the function
// pointer for the indirection to point at the trampoline.
std::string BodyPtrName = (F->getName() + "$address").str();
GlobalVariable *FunctionBodyPointer =
- createImplPointer(*F, BodyPtrName, CallbackInfo.getAddress());
+ createImplPointer(*F, BodyPtrName,
+ createIRTypedAddress(*F->getFunctionType(),
+ CallbackInfo.getAddress()));
makeStub(*F, *FunctionBodyPointer);
// Step 4) Add the module containing the stub to the JIT.
SessionContext &Session;
Mangler Mang;
+ SectionMemoryManager CCMgrMemMgr;
ObjLayerT ObjectLayer;
CompileLayerT CompileLayer;
LazyEmitLayerT LazyEmitLayer;
#include "llvm/Analysis/Passes.h"
#include "llvm/ExecutionEngine/Orc/CompileUtils.h"
#include "llvm/ExecutionEngine/Orc/IRCompileLayer.h"
+#include "llvm/ExecutionEngine/Orc/LambdaResolver.h"
#include "llvm/ExecutionEngine/Orc/LazyEmittingLayer.h"
#include "llvm/ExecutionEngine/Orc/ObjectLinkingLayer.h"
#include "llvm/IR/DataLayout.h"
// We need a memory manager to allocate memory and resolve symbols for this
// new module. Create one that resolves symbols by looking back into the
// JIT.
- auto MM = createLookasideRTDyldMM<SectionMemoryManager>(
- [&](const std::string &Name) {
- return findSymbol(Name).getAddress();
- },
- [](const std::string &S) { return 0; } );
-
- return CompileLayer.addModuleSet(singletonSet(std::move(M)), std::move(MM));
+ auto Resolver = createLambdaResolver(
+ [&](const std::string &Name) {
+ if (auto Sym = findSymbol(Name))
+ return RuntimeDyld::SymbolInfo(Sym.getAddress(),
+ Sym.getFlags());
+ return RuntimeDyld::SymbolInfo(nullptr);
+ },
+ [](const std::string &S) { return nullptr; }
+ );
+ return CompileLayer.addModuleSet(singletonSet(std::move(M)),
+ make_unique<SectionMemoryManager>(),
+ std::move(Resolver));
}
void removeModule(ModuleHandleT H) { CompileLayer.removeModuleSet(H); }
#include "llvm/Analysis/Passes.h"
#include "llvm/ExecutionEngine/Orc/CompileUtils.h"
#include "llvm/ExecutionEngine/Orc/IRCompileLayer.h"
+#include "llvm/ExecutionEngine/Orc/LambdaResolver.h"
#include "llvm/ExecutionEngine/Orc/LazyEmittingLayer.h"
#include "llvm/ExecutionEngine/Orc/ObjectLinkingLayer.h"
#include "llvm/IR/DataLayout.h"
// We need a memory manager to allocate memory and resolve symbols for this
// new module. Create one that resolves symbols by looking back into the
// JIT.
- auto MM = createLookasideRTDyldMM<SectionMemoryManager>(
- [&](const std::string &Name) {
- return findSymbol(Name).getAddress();
- },
- [](const std::string &S) { return 0; } );
+ auto Resolver = createLambdaResolver(
+ [&](const std::string &Name) {
+ if (auto Sym = findSymbol(Name))
+ return RuntimeDyld::SymbolInfo(Sym.getAddress(),
+ Sym.getFlags());
+ return RuntimeDyld::SymbolInfo(nullptr);
+ },
+ [](const std::string &S) { return nullptr; } );
return LazyEmitLayer.addModuleSet(singletonSet(std::move(M)),
- std::move(MM));
+ make_unique<SectionMemoryManager>(),
+ std::move(Resolver));
}
void removeModule(ModuleHandleT H) { LazyEmitLayer.removeModuleSet(H); }
#include "llvm/Analysis/Passes.h"
#include "llvm/ExecutionEngine/Orc/CompileUtils.h"
#include "llvm/ExecutionEngine/Orc/IRCompileLayer.h"
+#include "llvm/ExecutionEngine/Orc/LambdaResolver.h"
#include "llvm/ExecutionEngine/Orc/LazyEmittingLayer.h"
#include "llvm/ExecutionEngine/Orc/ObjectLinkingLayer.h"
#include "llvm/IR/DataLayout.h"
// We need a memory manager to allocate memory and resolve symbols for this
// new module. Create one that resolves symbols by looking back into the
// JIT.
- auto MM = createLookasideRTDyldMM<SectionMemoryManager>(
- [&](const std::string &Name) {
- // First try to find 'Name' within the JIT.
- if (auto Symbol = findSymbol(Name))
- return Symbol.getAddress();
-
- // If we don't already have a definition of 'Name' then search
- // the ASTs.
- return searchFunctionASTs(Name);
- },
- [](const std::string &S) { return 0; } );
+ auto Resolver = createLambdaResolver(
+ [&](const std::string &Name) {
+ // First try to find 'Name' within the JIT.
+ if (auto Symbol = findSymbol(Name))
+ return RuntimeDyld::SymbolInfo(Symbol.getAddress(),
+ Symbol.getFlags());
+
+ // If we don't already have a definition of 'Name' then search
+ // the ASTs.
+ return searchFunctionASTs(Name);
+ },
+ [](const std::string &S) { return nullptr; } );
return LazyEmitLayer.addModuleSet(singletonSet(std::move(M)),
- std::move(MM));
+ make_unique<SectionMemoryManager>(),
+ std::move(Resolver));
}
void removeModule(ModuleHandleT H) { LazyEmitLayer.removeModuleSet(H); }
// This method searches the FunctionDefs map for a definition of 'Name'. If it
// finds one it generates a stub for it and returns the address of the stub.
- TargetAddress searchFunctionASTs(const std::string &Name) {
+ RuntimeDyld::SymbolInfo searchFunctionASTs(const std::string &Name) {
auto DefI = FunctionDefs.find(Name);
if (DefI == FunctionDefs.end())
return 0;
// IRGen the AST, add it to the JIT, and return the address for it.
auto H = addModule(IRGen(Session, *FnAST));
- return findSymbolIn(H, Name).getAddress();
+ auto Sym = findSymbolIn(H, Name);
+ return RuntimeDyld::SymbolInfo(Sym.getAddress(), Sym.getFlags());
}
SessionContext &Session;
#ifndef LLVM_EXECUTIONENGINE_EXECUTIONENGINE_H
#define LLVM_EXECUTIONENGINE_EXECUTIONENGINE_H
+#include "RuntimeDyld.h"
#include "llvm-c/ExecutionEngine.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h"
class GlobalValue;
class JITEventListener;
class MachineCodeInfo;
+class MCJITMemoryManager;
class MutexGuard;
class ObjectCache;
class RTDyldMemoryManager;
virtual char *getMemoryForGV(const GlobalVariable *GV);
static ExecutionEngine *(*MCJITCtor)(
- std::unique_ptr<Module> M,
- std::string *ErrorStr,
- std::unique_ptr<RTDyldMemoryManager> MCJMM,
- std::unique_ptr<TargetMachine> TM);
+ std::unique_ptr<Module> M,
+ std::string *ErrorStr,
+ std::shared_ptr<MCJITMemoryManager> MM,
+ std::shared_ptr<RuntimeDyld::SymbolResolver> SR,
+ std::unique_ptr<TargetMachine> TM);
static ExecutionEngine *(*OrcMCJITReplacementCtor)(
- std::string *ErrorStr,
- std::unique_ptr<RTDyldMemoryManager> OrcJMM,
- std::unique_ptr<TargetMachine> TM);
+ std::string *ErrorStr,
+ std::shared_ptr<MCJITMemoryManager> MM,
+ std::shared_ptr<RuntimeDyld::SymbolResolver> SR,
+ std::unique_ptr<TargetMachine> TM);
static ExecutionEngine *(*InterpCtor)(std::unique_ptr<Module> M,
std::string *ErrorStr);
EngineKind::Kind WhichEngine;
std::string *ErrorStr;
CodeGenOpt::Level OptLevel;
- std::unique_ptr<RTDyldMemoryManager> MCJMM;
+ std::shared_ptr<MCJITMemoryManager> MemMgr;
+ std::shared_ptr<RuntimeDyld::SymbolResolver> Resolver;
TargetOptions Options;
Reloc::Model RelocModel;
CodeModel::Model CMModel;
/// memory manager. This option defaults to NULL.
EngineBuilder &setMCJITMemoryManager(std::unique_ptr<RTDyldMemoryManager> mcjmm);
+ EngineBuilder&
+ setMemoryManager(std::unique_ptr<MCJITMemoryManager> MM);
+
+ EngineBuilder&
+ setSymbolResolver(std::unique_ptr<RuntimeDyld::SymbolResolver> SR);
+
/// setErrorStr - Set the error string to write to on error. This option
/// defaults to NULL.
EngineBuilder &setErrorStr(std::string *e) {
#define LLVM_EXECUTIONENGINE_ORC_COMPILEONDEMANDLAYER_H
#include "IndirectionUtils.h"
-#include "LookasideRTDyldMM.h"
+#include "LambdaResolver.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ExecutionEngine/SectionMemoryManager.h"
#include <list>
typedef typename ModuleSetInfoListT::iterator ModuleSetHandleT;
// @brief Fallback lookup functor.
- typedef std::function<uint64_t(const std::string &)> LookupFtor;
+ typedef std::function<RuntimeDyld::SymbolInfo(const std::string &)> LookupFtor;
/// @brief Construct a compile-on-demand layer instance.
CompileOnDemandLayer(BaseLayerT &BaseLayer, CompileCallbackMgrT &CallbackMgr)
// If the user didn't supply a fallback lookup then just use
// getSymbolAddress.
if (!FallbackLookup)
- FallbackLookup = [=](const std::string &Name) {
- return findSymbol(Name, true).getAddress();
- };
+ FallbackLookup =
+ [=](const std::string &Name) -> RuntimeDyld::SymbolInfo {
+ if (auto Symbol = findSymbol(Name, true))
+ return RuntimeDyld::SymbolInfo(Symbol.getAddress(),
+ Symbol.getFlags());
+ return nullptr;
+ };
// Create a lookup context and ModuleSetInfo for this module set.
// For the purposes of symbol resolution the set Ms will be treated as if
Function *Proto = StubsModule->getFunction(Name);
assert(Proto && "Failed to clone function decl into stubs module.");
auto CallbackInfo =
- CompileCallbackMgr.getCompileCallback(*Proto->getFunctionType());
+ CompileCallbackMgr.getCompileCallback(Proto->getContext());
GlobalVariable *FunctionBodyPointer =
createImplPointer(*Proto, Name + AddrSuffix,
createIRTypedAddress(*Proto->getFunctionType(),
MSet.push_back(std::move(M));
auto DylibLookup = MSI.Lookup;
- auto MM =
- createLookasideRTDyldMM<SectionMemoryManager>(
+ auto Resolver =
+ createLambdaResolver(
[=](const std::string &Name) {
if (auto Symbol = DylibLookup->findSymbol(LogicalModule, Name))
- return Symbol.getAddress();
+ return RuntimeDyld::SymbolInfo(Symbol.getAddress(),
+ Symbol.getFlags());
return FallbackLookup(Name);
},
- [=](const std::string &Name) {
- return DylibLookup->findSymbol(LogicalModule, Name).getAddress();
+ [=](const std::string &Name) -> RuntimeDyld::SymbolInfo {
+ if (auto Symbol = DylibLookup->findSymbol(LogicalModule, Name))
+ return RuntimeDyld::SymbolInfo(Symbol.getAddress(),
+ Symbol.getFlags());
+ return nullptr;
});
BaseLayerModuleSetHandleT H =
- BaseLayer.addModuleSet(std::move(MSet), std::move(MM));
+ BaseLayer.addModuleSet(std::move(MSet),
+ make_unique<SectionMemoryManager>(),
+ std::move(Resolver));
// Add this module to the logical module lookup.
DylibLookup->addToLogicalModule(LogicalModule, H);
MSI.BaseLayerModuleSetHandles.push_back(H);
// manager MM.
///
/// @return A handle for the added modules.
- template <typename ModuleSetT>
+ template <typename ModuleSetT, typename MemoryManagerPtrT,
+ typename SymbolResolverPtrT>
ModuleSetHandleT addModuleSet(ModuleSetT Ms,
- std::unique_ptr<RTDyldMemoryManager> MM) {
+ MemoryManagerPtrT MemMgr,
+ SymbolResolverPtrT Resolver) {
OwningObjectVec Objects;
OwningBufferVec Buffers;
}
ModuleSetHandleT H =
- BaseLayer.addObjectSet(Objects, std::move(MM));
+ BaseLayer.addObjectSet(Objects, std::move(MemMgr), std::move(Resolver));
BaseLayer.takeOwnershipOfBuffers(H, std::move(Buffers));
#include "JITSymbol.h"
#include "llvm/ADT/DenseSet.h"
+#include "llvm/ExecutionEngine/RuntimeDyld.h"
#include "llvm/IR/IRBuilder.h"
#include "llvm/IR/Mangler.h"
#include "llvm/IR/Module.h"
}
/// @brief Get/create a compile callback with the given signature.
- virtual CompileCallbackInfo getCompileCallback(FunctionType &FT) = 0;
+ virtual CompileCallbackInfo getCompileCallback(LLVMContext &Context) = 0;
protected:
/// there is no existing callback trampoline.
/// (Trampolines are allocated in blocks for
/// efficiency.)
- JITCompileCallbackManager(JITLayerT &JIT, LLVMContext &Context,
+ JITCompileCallbackManager(JITLayerT &JIT, RuntimeDyld::MemoryManager &MemMgr,
+ LLVMContext &Context,
TargetAddress ErrorHandlerAddress,
unsigned NumTrampolinesPerBlock)
: JITCompileCallbackManagerBase(ErrorHandlerAddress,
NumTrampolinesPerBlock),
- JIT(JIT) {
+ JIT(JIT), MemMgr(MemMgr) {
emitResolverBlock(Context);
}
/// @brief Get/create a compile callback with the given signature.
- CompileCallbackInfo getCompileCallback(FunctionType &FT) final {
- TargetAddress TrampolineAddr = getAvailableTrampolineAddr(FT.getContext());
+ CompileCallbackInfo getCompileCallback(LLVMContext &Context) final {
+ TargetAddress TrampolineAddr = getAvailableTrampolineAddr(Context);
auto &CallbackHandler =
this->ActiveTrampolines[TrampolineAddr];
std::unique_ptr<Module> M(new Module("resolver_block_module",
Context));
TargetT::insertResolverBlock(*M, *this);
- auto H = JIT.addModuleSet(SingletonSet(std::move(M)), nullptr);
+ auto H = JIT.addModuleSet(SingletonSet(std::move(M)), &MemMgr,
+ static_cast<RuntimeDyld::SymbolResolver*>(
+ nullptr));
JIT.emitAndFinalize(H);
auto ResolverBlockSymbol =
JIT.findSymbolIn(H, TargetT::ResolverBlockName, false);
TargetT::insertCompileCallbackTrampolines(*M, ResolverBlockAddr,
this->NumTrampolinesPerBlock,
this->ActiveTrampolines.size());
- auto H = JIT.addModuleSet(SingletonSet(std::move(M)), nullptr);
+ auto H = JIT.addModuleSet(SingletonSet(std::move(M)), &MemMgr,
+ static_cast<RuntimeDyld::SymbolResolver*>(
+ nullptr));
JIT.emitAndFinalize(H);
for (unsigned I = 0; I < this->NumTrampolinesPerBlock; ++I) {
std::string Name = GetLabelName(I);
}
JITLayerT &JIT;
+ RuntimeDyld::MemoryManager &MemMgr;
TargetAddress ResolverBlockAddr;
};
/// @brief Represents a symbol in the JIT.
class JITSymbol : public JITSymbolBase {
-public:
+public:
typedef std::function<TargetAddress()> GetAddressFtor;
--- /dev/null
+//===-- LambdaResolverMM - Redirect symbol lookup via a functor -*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Defines a RuntimeDyld::SymbolResolver subclass that uses a user-supplied
+// functor for symbol resolution.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_EXECUTIONENGINE_ORC_LAMBDARESOLVER_H
+#define LLVM_EXECUTIONENGINE_ORC_LAMBDARESOLVER_H
+
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/ExecutionEngine/RuntimeDyld.h"
+#include <memory>
+#include <vector>
+
+namespace llvm {
+namespace orc {
+
+template <typename ExternalLookupFtorT, typename DylibLookupFtorT>
+class LambdaResolver : public RuntimeDyld::SymbolResolver {
+public:
+
+ LambdaResolver(ExternalLookupFtorT ExternalLookupFtor,
+ DylibLookupFtorT DylibLookupFtor)
+ : ExternalLookupFtor(ExternalLookupFtor),
+ DylibLookupFtor(DylibLookupFtor) {}
+
+ RuntimeDyld::SymbolInfo findSymbol(const std::string &Name) final {
+ return ExternalLookupFtor(Name);
+ }
+
+ RuntimeDyld::SymbolInfo
+ findSymbolInLogicalDylib(const std::string &Name) final {
+ return DylibLookupFtor(Name);
+ }
+
+private:
+ ExternalLookupFtorT ExternalLookupFtor;
+ DylibLookupFtorT DylibLookupFtor;
+};
+
+template <typename ExternalLookupFtorT,
+ typename DylibLookupFtorT>
+std::unique_ptr<LambdaResolver<ExternalLookupFtorT, DylibLookupFtorT>>
+createLambdaResolver(ExternalLookupFtorT ExternalLookupFtor,
+ DylibLookupFtorT DylibLookupFtor) {
+ typedef LambdaResolver<ExternalLookupFtorT, DylibLookupFtorT> LR;
+ return make_unique<LR>(std::move(ExternalLookupFtor),
+ std::move(DylibLookupFtor));
+}
+
+} // End namespace orc.
+} // End namespace llvm.
+
+#endif // LLVM_EXECUTIONENGINE_ORC_LAMBDARESOLVER_H
#define LLVM_EXECUTIONENGINE_ORC_LAZYEMITTINGLAYER_H
#include "JITSymbol.h"
-#include "LookasideRTDyldMM.h"
#include "llvm/ExecutionEngine/RTDyldMemoryManager.h"
#include "llvm/IR/GlobalValue.h"
#include "llvm/IR/Mangler.h"
#include "llvm/IR/Module.h"
+#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/StringMap.h"
#include <list>
BaseLayer.emitAndFinalize(Handle);
}
- template <typename ModuleSetT>
+ template <typename ModuleSetT, typename MemoryManagerPtrT,
+ typename SymbolResolverPtrT>
static std::unique_ptr<EmissionDeferredSet>
- create(BaseLayerT &B, ModuleSetT Ms,
- std::unique_ptr<RTDyldMemoryManager> MM);
+ create(BaseLayerT &B, ModuleSetT Ms, MemoryManagerPtrT MemMgr,
+ SymbolResolverPtrT Resolver);
protected:
virtual const GlobalValue* searchGVs(StringRef Name,
BaseLayerHandleT Handle;
};
- template <typename ModuleSetT>
+ template <typename ModuleSetT, typename MemoryManagerPtrT,
+ typename SymbolResolverPtrT>
class EmissionDeferredSetImpl : public EmissionDeferredSet {
public:
EmissionDeferredSetImpl(ModuleSetT Ms,
- std::unique_ptr<RTDyldMemoryManager> MM)
- : Ms(std::move(Ms)), MM(std::move(MM)) {}
+ MemoryManagerPtrT MemMgr,
+ SymbolResolverPtrT Resolver)
+ : Ms(std::move(Ms)), MemMgr(std::move(MemMgr)),
+ Resolver(std::move(Resolver)) {}
protected:
// We don't need the mangled names set any more: Once we've emitted this
// to the base layer we'll just look for symbols there.
MangledSymbols.reset();
- return BaseLayer.addModuleSet(std::move(Ms), std::move(MM));
+ return BaseLayer.addModuleSet(std::move(Ms), std::move(MemMgr),
+ std::move(Resolver));
}
private:
}
ModuleSetT Ms;
- std::unique_ptr<RTDyldMemoryManager> MM;
+ MemoryManagerPtrT MemMgr;
+ SymbolResolverPtrT Resolver;
mutable std::unique_ptr<StringMap<const GlobalValue*>> MangledSymbols;
};
LazyEmittingLayer(BaseLayerT &BaseLayer) : BaseLayer(BaseLayer) {}
/// @brief Add the given set of modules to the lazy emitting layer.
- template <typename ModuleSetT>
+ template <typename ModuleSetT, typename MemoryManagerPtrT,
+ typename SymbolResolverPtrT>
ModuleSetHandleT addModuleSet(ModuleSetT Ms,
- std::unique_ptr<RTDyldMemoryManager> MM) {
+ MemoryManagerPtrT MemMgr,
+ SymbolResolverPtrT Resolver) {
return ModuleSetList.insert(
ModuleSetList.end(),
- EmissionDeferredSet::create(BaseLayer, std::move(Ms), std::move(MM)));
+ EmissionDeferredSet::create(BaseLayer, std::move(Ms), std::move(MemMgr),
+ std::move(Resolver)));
}
/// @brief Remove the module set represented by the given handle.
};
template <typename BaseLayerT>
-template <typename ModuleSetT>
+template <typename ModuleSetT, typename MemoryManagerPtrT,
+ typename SymbolResolverPtrT>
std::unique_ptr<typename LazyEmittingLayer<BaseLayerT>::EmissionDeferredSet>
LazyEmittingLayer<BaseLayerT>::EmissionDeferredSet::create(
- BaseLayerT &B, ModuleSetT Ms, std::unique_ptr<RTDyldMemoryManager> MM) {
- return llvm::make_unique<EmissionDeferredSetImpl<ModuleSetT>>(std::move(Ms),
- std::move(MM));
+ BaseLayerT &B, ModuleSetT Ms, MemoryManagerPtrT MemMgr,
+ SymbolResolverPtrT Resolver) {
+ typedef EmissionDeferredSetImpl<ModuleSetT, MemoryManagerPtrT, SymbolResolverPtrT>
+ EDS;
+ return llvm::make_unique<EDS>(std::move(Ms), std::move(MemMgr),
+ std::move(Resolver));
}
} // End namespace orc.
+++ /dev/null
-//===- LookasideRTDyldMM - Redirect symbol lookup via a functor -*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// Defines an adapter for RuntimeDyldMM that allows lookups for external
-// symbols to go via a functor.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_EXECUTIONENGINE_ORC_LOOKASIDERTDYLDMM_H
-#define LLVM_EXECUTIONENGINE_ORC_LOOKASIDERTDYLDMM_H
-
-#include "llvm/ADT/STLExtras.h"
-#include <memory>
-#include <vector>
-
-namespace llvm {
-namespace orc {
-
-/// @brief Defines an adapter for RuntimeDyldMM that allows lookups for external
-/// symbols to go via a functor, before falling back to the lookup logic
-/// provided by the underlying RuntimeDyldMM instance.
-///
-/// This class is useful for redirecting symbol lookup back to various layers
-/// of a JIT component stack, e.g. to enable lazy module emission.
-///
-template <typename BaseRTDyldMM, typename ExternalLookupFtor,
- typename DylibLookupFtor>
-class LookasideRTDyldMM : public BaseRTDyldMM {
-public:
- /// @brief Create a LookasideRTDyldMM intance.
- LookasideRTDyldMM(ExternalLookupFtor ExternalLookup,
- DylibLookupFtor DylibLookup)
- : ExternalLookup(std::move(ExternalLookup)),
- DylibLookup(std::move(DylibLookup)) {}
-
- /// @brief Look up the given symbol address, first via the functor this
- /// instance was created with, then (if the symbol isn't found)
- /// via the underlying RuntimeDyldMM.
- uint64_t getSymbolAddress(const std::string &Name) override {
- if (uint64_t Addr = ExternalLookup(Name))
- return Addr;
- return BaseRTDyldMM::getSymbolAddress(Name);
- }
-
- uint64_t getSymbolAddressInLogicalDylib(const std::string &Name) override {
- if (uint64_t Addr = DylibLookup(Name))
- return Addr;
- return BaseRTDyldMM::getSymbolAddressInLogicalDylib(Name);
- };
-
- /// @brief Get a reference to the ExternalLookup functor.
- ExternalLookupFtor &getExternalLookup() { return ExternalLookup; }
-
- /// @brief Get a const-reference to the ExternalLookup functor.
- const ExternalLookupFtor &getExternalLookup() const { return ExternalLookup; }
-
- /// @brief Get a reference to the DylibLookup functor.
- DylibLookupFtor &getDylibLookup() { return DylibLookup; }
-
- /// @brief Get a const-reference to the DylibLookup functor.
- const DylibLookupFtor &getDylibLookup() const { return DylibLookup; }
-
-private:
- ExternalLookupFtor ExternalLookup;
- DylibLookupFtor DylibLookup;
-};
-
-/// @brief Create a LookasideRTDyldMM from a base memory manager type, an
-/// external lookup functor, and a dylib lookup functor.
-template <typename BaseRTDyldMM, typename ExternalLookupFtor,
- typename DylibLookupFtor>
-std::unique_ptr<
- LookasideRTDyldMM<BaseRTDyldMM, ExternalLookupFtor, DylibLookupFtor>>
-createLookasideRTDyldMM(ExternalLookupFtor &&ExternalLookup,
- DylibLookupFtor &&DylibLookup) {
- typedef LookasideRTDyldMM<BaseRTDyldMM, ExternalLookupFtor, DylibLookupFtor>
- ThisLookasideMM;
- return llvm::make_unique<ThisLookasideMM>(
- std::forward<ExternalLookupFtor>(ExternalLookup),
- std::forward<DylibLookupFtor>(DylibLookup));
-}
-
-} // End namespace orc.
-} // End namespace llvm.
-
-#endif // LLVM_EXECUTIONENGINE_ORC_LOOKASIDERTDYLDMM_H
#define LLVM_EXECUTIONENGINE_ORC_OBJECTLINKINGLAYER_H
#include "JITSymbol.h"
-#include "LookasideRTDyldMM.h"
#include "llvm/ExecutionEngine/ExecutionEngine.h"
#include "llvm/ExecutionEngine/SectionMemoryManager.h"
#include <list>
LinkedObjectSet(const LinkedObjectSet&) = delete;
void operator=(const LinkedObjectSet&) = delete;
public:
- LinkedObjectSet(std::unique_ptr<RTDyldMemoryManager> MM)
- : MM(std::move(MM)), RTDyld(llvm::make_unique<RuntimeDyld>(&*this->MM)),
+ LinkedObjectSet(RuntimeDyld::MemoryManager &MemMgr,
+ RuntimeDyld::SymbolResolver &Resolver)
+ : RTDyld(llvm::make_unique<RuntimeDyld>(MemMgr, Resolver)),
State(Raw) {}
- // MSVC 2012 cannot infer a move constructor, so write it out longhand.
- LinkedObjectSet(LinkedObjectSet &&O)
- : MM(std::move(O.MM)), RTDyld(std::move(O.RTDyld)), State(O.State) {}
+ virtual ~LinkedObjectSet() {}
std::unique_ptr<RuntimeDyld::LoadedObjectInfo>
addObject(const object::ObjectFile &Obj) {
bool NeedsFinalization() const { return (State == Raw); }
- void Finalize() {
- State = Finalizing;
- RTDyld->resolveRelocations();
- RTDyld->registerEHFrames();
- MM->finalizeMemory();
- OwnedBuffers.clear();
- State = Finalized;
- }
+ virtual void Finalize() = 0;
void mapSectionAddress(const void *LocalAddress, TargetAddress TargetAddr) {
assert((State != Finalized) &&
OwnedBuffers.push_back(std::move(B));
}
- private:
- std::unique_ptr<RTDyldMemoryManager> MM;
+ protected:
std::unique_ptr<RuntimeDyld> RTDyld;
enum { Raw, Finalizing, Finalized } State;
std::vector<std::unique_ptr<MemoryBuffer>> OwnedBuffers;
};
- typedef std::list<LinkedObjectSet> LinkedObjectSetListT;
+ typedef std::list<std::unique_ptr<LinkedObjectSet>> LinkedObjectSetListT;
public:
/// @brief Handle to a set of loaded objects.
template <typename OwningMBSet>
void takeOwnershipOfBuffers(ObjSetHandleT H, OwningMBSet MBs) {
for (auto &MB : MBs)
- H->takeOwnershipOfBuffer(std::move(MB));
+ (*H)->takeOwnershipOfBuffer(std::move(MB));
}
};
/// symbols.
template <typename NotifyLoadedFtor = DoNothingOnNotifyLoaded>
class ObjectLinkingLayer : public ObjectLinkingLayerBase {
+private:
+
+ template <typename MemoryManagerPtrT, typename SymbolResolverPtrT>
+ class ConcreteLinkedObjectSet : public LinkedObjectSet {
+ public:
+ ConcreteLinkedObjectSet(MemoryManagerPtrT MemMgr,
+ SymbolResolverPtrT Resolver)
+ : LinkedObjectSet(*MemMgr, *Resolver), MemMgr(std::move(MemMgr)),
+ Resolver(std::move(Resolver)) { }
+
+ void Finalize() override {
+ State = Finalizing;
+ RTDyld->resolveRelocations();
+ RTDyld->registerEHFrames();
+ MemMgr->finalizeMemory();
+ OwnedBuffers.clear();
+ State = Finalized;
+ }
+
+ private:
+ MemoryManagerPtrT MemMgr;
+ SymbolResolverPtrT Resolver;
+ };
+
+ template <typename MemoryManagerPtrT, typename SymbolResolverPtrT>
+ std::unique_ptr<LinkedObjectSet>
+ createLinkedObjectSet(MemoryManagerPtrT MemMgr, SymbolResolverPtrT Resolver) {
+ typedef ConcreteLinkedObjectSet<MemoryManagerPtrT, SymbolResolverPtrT> LOS;
+ return llvm::make_unique<LOS>(std::move(MemMgr), std::move(Resolver));
+ }
+
public:
/// @brief LoadedObjectInfo list. Contains a list of owning pointers to
typedef std::vector<std::unique_ptr<RuntimeDyld::LoadedObjectInfo>>
LoadedObjInfoList;
- /// @brief Functor to create RTDyldMemoryManager instances.
- typedef std::function<std::unique_ptr<RTDyldMemoryManager>()> CreateRTDyldMMFtor;
-
/// @brief Functor for receiving finalization notifications.
typedef std::function<void(ObjSetHandleT)> NotifyFinalizedFtor;
/// @brief Construct an ObjectLinkingLayer with the given NotifyLoaded,
- /// NotifyFinalized and CreateMemoryManager functors.
+ /// and NotifyFinalized functors.
ObjectLinkingLayer(
- CreateRTDyldMMFtor CreateMemoryManager = CreateRTDyldMMFtor(),
NotifyLoadedFtor NotifyLoaded = NotifyLoadedFtor(),
NotifyFinalizedFtor NotifyFinalized = NotifyFinalizedFtor())
: NotifyLoaded(std::move(NotifyLoaded)),
- NotifyFinalized(std::move(NotifyFinalized)),
- CreateMemoryManager(std::move(CreateMemoryManager)) {}
+ NotifyFinalized(std::move(NotifyFinalized)) {}
/// @brief Add a set of objects (or archives) that will be treated as a unit
/// for the purposes of symbol lookup and memory management.
/// This version of this method allows the client to pass in an
/// RTDyldMemoryManager instance that will be used to allocate memory and look
/// up external symbol addresses for the given objects.
- template <typename ObjSetT>
+ template <typename ObjSetT,
+ typename MemoryManagerPtrT,
+ typename SymbolResolverPtrT>
ObjSetHandleT addObjectSet(const ObjSetT &Objects,
- std::unique_ptr<RTDyldMemoryManager> MM) {
-
- if (!MM) {
- assert(CreateMemoryManager &&
- "No memory manager or memory manager creator provided.");
- MM = CreateMemoryManager();
- }
-
- ObjSetHandleT Handle = LinkedObjSetList.insert(
- LinkedObjSetList.end(), LinkedObjectSet(std::move(MM)));
- LinkedObjectSet &LOS = *Handle;
+ MemoryManagerPtrT MemMgr,
+ SymbolResolverPtrT Resolver) {
+ ObjSetHandleT Handle =
+ LinkedObjSetList.insert(
+ LinkedObjSetList.end(),
+ createLinkedObjectSet(std::move(MemMgr), std::move(Resolver)));
+
+ LinkedObjectSet &LOS = **Handle;
LoadedObjInfoList LoadedObjInfos;
for (auto &Obj : Objects)
/// given object set.
JITSymbol findSymbolIn(ObjSetHandleT H, StringRef Name,
bool ExportedSymbolsOnly) {
- if (auto Sym = H->getSymbol(Name)) {
+ if (auto Sym = (*H)->getSymbol(Name)) {
if (Sym.isExported() || !ExportedSymbolsOnly) {
auto Addr = Sym.getAddress();
auto Flags = Sym.getFlags();
- if (!H->NeedsFinalization()) {
+ if (!(*H)->NeedsFinalization()) {
// If this instance has already been finalized then we can just return
// the address.
return JITSymbol(Addr, Flags);
// it. The functor still needs to double-check whether finalization is
// required, in case someone else finalizes this set before the
// functor is called.
- auto GetAddress =
+ auto GetAddress =
[this, Addr, H]() {
- if (H->NeedsFinalization()) {
- H->Finalize();
+ if ((*H)->NeedsFinalization()) {
+ (*H)->Finalize();
if (NotifyFinalized)
NotifyFinalized(H);
}
/// @brief Map section addresses for the objects associated with the handle H.
void mapSectionAddress(ObjSetHandleT H, const void *LocalAddress,
TargetAddress TargetAddr) {
- H->mapSectionAddress(LocalAddress, TargetAddr);
+ (*H)->mapSectionAddress(LocalAddress, TargetAddr);
}
/// @brief Immediately emit and finalize the object set represented by the
/// given handle.
/// @param H Handle for object set to emit/finalize.
void emitAndFinalize(ObjSetHandleT H) {
- H->Finalize();
+ (*H)->Finalize();
if (NotifyFinalized)
NotifyFinalized(H);
}
LinkedObjectSetListT LinkedObjSetList;
NotifyLoadedFtor NotifyLoaded;
NotifyFinalizedFtor NotifyFinalized;
- CreateRTDyldMMFtor CreateMemoryManager;
};
} // End namespace orc.
#ifndef LLVM_EXECUTIONENGINE_RTDYLDMEMORYMANAGER_H
#define LLVM_EXECUTIONENGINE_RTDYLDMEMORYMANAGER_H
+#include "RuntimeDyld.h"
#include "llvm-c/ExecutionEngine.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/CBindingWrapping.h"
class ObjectFile;
}
+class MCJITMemoryManager : public RuntimeDyld::MemoryManager {
+public:
+ /// This method is called after an object has been loaded into memory but
+ /// before relocations are applied to the loaded sections. The object load
+ /// may have been initiated by MCJIT to resolve an external symbol for another
+ /// object that is being finalized. In that case, the object about which
+ /// the memory manager is being notified will be finalized immediately after
+ /// the memory manager returns from this call.
+ ///
+ /// Memory managers which are preparing code for execution in an external
+ /// address space can use this call to remap the section addresses for the
+ /// newly loaded object.
+ virtual void notifyObjectLoaded(ExecutionEngine *EE,
+ const object::ObjectFile &) {}
+};
+
// RuntimeDyld clients often want to handle the memory management of
// what gets placed where. For JIT clients, this is the subset of
// JITMemoryManager required for dynamic loading of binaries.
//
// FIXME: As the RuntimeDyld fills out, additional routines will be needed
// for the varying types of objects to be allocated.
-class RTDyldMemoryManager {
+class RTDyldMemoryManager : public MCJITMemoryManager,
+ public RuntimeDyld::SymbolResolver {
RTDyldMemoryManager(const RTDyldMemoryManager&) = delete;
void operator=(const RTDyldMemoryManager&) = delete;
public:
RTDyldMemoryManager() {}
virtual ~RTDyldMemoryManager();
- /// Allocate a memory block of (at least) the given size suitable for
- /// executable code. The SectionID is a unique identifier assigned by the JIT
- /// engine, and optionally recorded by the memory manager to access a loaded
- /// section.
- virtual uint8_t *allocateCodeSection(
- uintptr_t Size, unsigned Alignment, unsigned SectionID,
- StringRef SectionName) = 0;
-
- /// Allocate a memory block of (at least) the given size suitable for data.
- /// The SectionID is a unique identifier assigned by the JIT engine, and
- /// optionally recorded by the memory manager to access a loaded section.
- virtual uint8_t *allocateDataSection(
- uintptr_t Size, unsigned Alignment, unsigned SectionID,
- StringRef SectionName, bool IsReadOnly) = 0;
-
- /// Inform the memory manager about the total amount of memory required to
- /// allocate all sections to be loaded:
- /// \p CodeSize - the total size of all code sections
- /// \p DataSizeRO - the total size of all read-only data sections
- /// \p DataSizeRW - the total size of all read-write data sections
- ///
- /// Note that by default the callback is disabled. To enable it
- /// redefine the method needsToReserveAllocationSpace to return true.
- virtual void reserveAllocationSpace(
- uintptr_t CodeSize, uintptr_t DataSizeRO, uintptr_t DataSizeRW) { }
-
- /// Override to return true to enable the reserveAllocationSpace callback.
- virtual bool needsToReserveAllocationSpace() { return false; }
-
- /// Register the EH frames with the runtime so that c++ exceptions work.
- ///
- /// \p Addr parameter provides the local address of the EH frame section
- /// data, while \p LoadAddr provides the address of the data in the target
- /// address space. If the section has not been remapped (which will usually
- /// be the case for local execution) these two values will be the same.
- virtual void registerEHFrames(uint8_t *Addr, uint64_t LoadAddr, size_t Size);
-
- virtual void deregisterEHFrames(uint8_t *Addr, uint64_t LoadAddr, size_t Size);
+ void registerEHFrames(uint8_t *Addr, uint64_t LoadAddr, size_t Size) override;
+ void deregisterEHFrames(uint8_t *Addr, uint64_t LoadAddr, size_t Size) override;
/// This method returns the address of the specified function or variable in
/// the current process.
static uint64_t getSymbolAddressInProcess(const std::string &Name);
+ /// Legacy symbol lookup - DEPRECATED! Please override findSymbol instead.
+ ///
/// This method returns the address of the specified function or variable.
/// It is used to resolve symbols during module linking.
virtual uint64_t getSymbolAddress(const std::string &Name) {
return getSymbolAddressInProcess(Name);
}
- /// This method returns the address of the specified symbol if it exists
- /// within the logical dynamic library represented by this
- /// RTDyldMemoryManager. Unlike getSymbolAddress, queries through this
- /// interface should return addresses for hidden symbols.
+ /// This method returns a RuntimeDyld::SymbolInfo for the specified function
+ /// or variable. It is used to resolve symbols during module linking.
+ ///
+ /// By default this falls back on the legacy lookup method:
+ /// 'getSymbolAddress'. The address returned by getSymbolAddress is treated as
+ /// a strong, exported symbol, consistent with historical treatment by
+ /// RuntimeDyld.
///
- /// This is of particular importance for the Orc JIT APIs, which support lazy
- /// compilation by breaking up modules: Each of those broken out modules
- /// must be able to resolve hidden symbols provided by the others. Clients
- /// writing memory managers for MCJIT can usually ignore this method.
+ /// Clients writing custom RTDyldMemoryManagers are encouraged to override
+ /// this method and return a SymbolInfo with the flags set correctly. This is
+ /// necessary for RuntimeDyld to correctly handle weak and non-exported symbols.
+ RuntimeDyld::SymbolInfo findSymbol(const std::string &Name) override {
+ return RuntimeDyld::SymbolInfo(getSymbolAddress(Name),
+ JITSymbolFlags::Exported);
+ }
+
+ /// Legacy symbol lookup -- DEPRECATED! Please override
+ /// findSymbolInLogicalDylib instead.
///
- /// This method will be queried by RuntimeDyld when checking for previous
- /// definitions of common symbols. It will *not* be queried by default when
- /// resolving external symbols (this minimises the link-time overhead for
- /// MCJIT clients who don't care about Orc features). If you are writing a
- /// RTDyldMemoryManager for Orc and want "external" symbol resolution to
- /// search the logical dylib, you should override your getSymbolAddress
- /// method call this method directly.
+ /// Default to treating all modules as separate.
virtual uint64_t getSymbolAddressInLogicalDylib(const std::string &Name) {
return 0;
}
+ /// Default to treating all modules as separate.
+ ///
+ /// By default this falls back on the legacy lookup method:
+ /// 'getSymbolAddressInLogicalDylib'. The address returned by
+ /// getSymbolAddressInLogicalDylib is treated as a strong, exported symbol,
+ /// consistent with historical treatment by RuntimeDyld.
+ ///
+ /// Clients writing custom RTDyldMemoryManagers are encouraged to override
+ /// this method and return a SymbolInfo with the flags set correctly. This is
+ /// necessary for RuntimeDyld to correctly handle weak and non-exported symbols.
+ RuntimeDyld::SymbolInfo
+ findSymbolInLogicalDylib(const std::string &Name) override {
+ return RuntimeDyld::SymbolInfo(getSymbolAddressInLogicalDylib(Name),
+ JITSymbolFlags::Exported);
+ }
+
/// This method returns the address of the specified function. As such it is
/// only useful for resolving library symbols, not code generated symbols.
///
/// MCJIT or RuntimeDyld. Use getSymbolAddress instead.
virtual void *getPointerToNamedFunction(const std::string &Name,
bool AbortOnFailure = true);
-
- /// This method is called after an object has been loaded into memory but
- /// before relocations are applied to the loaded sections. The object load
- /// may have been initiated by MCJIT to resolve an external symbol for another
- /// object that is being finalized. In that case, the object about which
- /// the memory manager is being notified will be finalized immediately after
- /// the memory manager returns from this call.
- ///
- /// Memory managers which are preparing code for execution in an external
- /// address space can use this call to remap the section addresses for the
- /// newly loaded object.
- virtual void notifyObjectLoaded(ExecutionEngine *EE,
- const object::ObjectFile &) {}
-
- /// This method is called when object loading is complete and section page
- /// permissions can be applied. It is up to the memory manager implementation
- /// to decide whether or not to act on this method. The memory manager will
- /// typically allocate all sections as read-write and then apply specific
- /// permissions when this method is called. Code sections cannot be executed
- /// until this function has been called. In addition, any cache coherency
- /// operations needed to reliably use the memory are also performed.
- ///
- /// Returns true if an error occurred, false otherwise.
- virtual bool finalizeMemory(std::string *ErrMsg = nullptr) = 0;
};
// Create wrappers for C Binding types (see CBindingWrapping.h).
} // namespace llvm
+
#endif
#include "JITSymbolFlags.h"
#include "llvm/ADT/StringRef.h"
-#include "llvm/ExecutionEngine/RTDyldMemoryManager.h"
#include "llvm/Support/Memory.h"
#include <memory>
class RuntimeDyldImpl;
class RuntimeDyldCheckerImpl;
-
+
class RuntimeDyld {
friend class RuntimeDyldCheckerImpl;
RuntimeDyld(const RuntimeDyld &) = delete;
void operator=(const RuntimeDyld &) = delete;
- // RuntimeDyldImpl is the actual class. RuntimeDyld is just the public
- // interface.
- std::unique_ptr<RuntimeDyldImpl> Dyld;
- RTDyldMemoryManager *MM;
- bool ProcessAllSections;
- RuntimeDyldCheckerImpl *Checker;
protected:
// Change the address associated with a section when resolving relocations.
// Any relocations already associated with the symbol will be re-resolved.
unsigned BeginIdx, EndIdx;
};
- RuntimeDyld(RTDyldMemoryManager *);
+ /// \brief Memory Management.
+ class MemoryManager {
+ public:
+ virtual ~MemoryManager() {};
+
+ /// Allocate a memory block of (at least) the given size suitable for
+ /// executable code. The SectionID is a unique identifier assigned by the
+ /// RuntimeDyld instance, and optionally recorded by the memory manager to
+ /// access a loaded section.
+ virtual uint8_t *allocateCodeSection(uintptr_t Size, unsigned Alignment,
+ unsigned SectionID,
+ StringRef SectionName) = 0;
+
+ /// Allocate a memory block of (at least) the given size suitable for data.
+ /// The SectionID is a unique identifier assigned by the JIT engine, and
+ /// optionally recorded by the memory manager to access a loaded section.
+ virtual uint8_t *allocateDataSection(uintptr_t Size, unsigned Alignment,
+ unsigned SectionID,
+ StringRef SectionName,
+ bool IsReadOnly) = 0;
+
+ /// Inform the memory manager about the total amount of memory required to
+ /// allocate all sections to be loaded:
+ /// \p CodeSize - the total size of all code sections
+ /// \p DataSizeRO - the total size of all read-only data sections
+ /// \p DataSizeRW - the total size of all read-write data sections
+ ///
+ /// Note that by default the callback is disabled. To enable it
+ /// redefine the method needsToReserveAllocationSpace to return true.
+ virtual void reserveAllocationSpace(uintptr_t CodeSize,
+ uintptr_t DataSizeRO,
+ uintptr_t DataSizeRW) {}
+
+ /// Override to return true to enable the reserveAllocationSpace callback.
+ virtual bool needsToReserveAllocationSpace() { return false; }
+
+ /// Register the EH frames with the runtime so that c++ exceptions work.
+ ///
+ /// \p Addr parameter provides the local address of the EH frame section
+ /// data, while \p LoadAddr provides the address of the data in the target
+ /// address space. If the section has not been remapped (which will usually
+ /// be the case for local execution) these two values will be the same.
+ virtual void registerEHFrames(uint8_t *Addr, uint64_t LoadAddr,
+ size_t Size) = 0;
+ virtual void deregisterEHFrames(uint8_t *addr, uint64_t LoadAddr,
+ size_t Size) = 0;
+
+ /// This method is called when object loading is complete and section page
+ /// permissions can be applied. It is up to the memory manager implementation
+ /// to decide whether or not to act on this method. The memory manager will
+ /// typically allocate all sections as read-write and then apply specific
+ /// permissions when this method is called. Code sections cannot be executed
+ /// until this function has been called. In addition, any cache coherency
+ /// operations needed to reliably use the memory are also performed.
+ ///
+ /// Returns true if an error occurred, false otherwise.
+ virtual bool finalizeMemory(std::string *ErrMsg = nullptr) = 0;
+
+ private:
+ virtual void anchor();
+ };
+
+ /// \brief Symbol resolution.
+ class SymbolResolver {
+ public:
+ virtual ~SymbolResolver() {};
+
+ /// This method returns the address of the specified function or variable.
+ /// It is used to resolve symbols during module linking.
+ virtual SymbolInfo findSymbol(const std::string &Name) = 0;
+
+ /// This method returns the address of the specified symbol if it exists
+ /// within the logical dynamic library represented by this
+ /// RTDyldMemoryManager. Unlike getSymbolAddress, queries through this
+ /// interface should return addresses for hidden symbols.
+ ///
+ /// This is of particular importance for the Orc JIT APIs, which support lazy
+ /// compilation by breaking up modules: Each of those broken out modules
+ /// must be able to resolve hidden symbols provided by the others. Clients
+ /// writing memory managers for MCJIT can usually ignore this method.
+ ///
+ /// This method will be queried by RuntimeDyld when checking for previous
+ /// definitions of common symbols. It will *not* be queried by default when
+ /// resolving external symbols (this minimises the link-time overhead for
+ /// MCJIT clients who don't care about Orc features). If you are writing a
+ /// RTDyldMemoryManager for Orc and want "external" symbol resolution to
+ /// search the logical dylib, you should override your getSymbolAddress
+ /// method call this method directly.
+ virtual SymbolInfo findSymbolInLogicalDylib(const std::string &Name) = 0;
+ private:
+ virtual void anchor();
+ };
+
+ /// \brief Construct a RuntimeDyld instance.
+ RuntimeDyld(MemoryManager &MemMgr, SymbolResolver &Resolver);
~RuntimeDyld();
/// Add the referenced object file to the list of objects to be loaded and
assert(!Dyld && "setProcessAllSections must be called before loadObject.");
this->ProcessAllSections = ProcessAllSections;
}
+
+private:
+ // RuntimeDyldImpl is the actual class. RuntimeDyld is just the public
+ // interface.
+ std::unique_ptr<RuntimeDyldImpl> Dyld;
+ MemoryManager &MemMgr;
+ SymbolResolver &Resolver;
+ bool ProcessAllSections;
+ RuntimeDyldCheckerImpl *Checker;
};
} // end namespace llvm
#define LLVM_EXECUTIONENGINE_SECTIONMEMORYMANAGER_H
#include "llvm/ADT/SmallVector.h"
-#include "llvm/ExecutionEngine/RuntimeDyld.h"
+#include "llvm/ExecutionEngine/RTDyldMemoryManager.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/Memory.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/ExecutionEngine/GenericValue.h"
#include "llvm/ExecutionEngine/JITEventListener.h"
+#include "llvm/ExecutionEngine/RTDyldMemoryManager.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/DataLayout.h"
#include "llvm/IR/DerivedTypes.h"
ExecutionEngine *(*ExecutionEngine::MCJITCtor)(
std::unique_ptr<Module> M, std::string *ErrorStr,
- std::unique_ptr<RTDyldMemoryManager> MCJMM,
+ std::shared_ptr<MCJITMemoryManager> MemMgr,
+ std::shared_ptr<RuntimeDyld::SymbolResolver> Resolver,
std::unique_ptr<TargetMachine> TM) = nullptr;
ExecutionEngine *(*ExecutionEngine::OrcMCJITReplacementCtor)(
- std::string *ErrorStr, std::unique_ptr<RTDyldMemoryManager> OrcJMM,
+ std::string *ErrorStr, std::shared_ptr<MCJITMemoryManager> MemMgr,
+ std::shared_ptr<RuntimeDyld::SymbolResolver> Resolver,
std::unique_ptr<TargetMachine> TM) = nullptr;
ExecutionEngine *(*ExecutionEngine::InterpCtor)(std::unique_ptr<Module> M,
EngineBuilder::EngineBuilder(std::unique_ptr<Module> M)
: M(std::move(M)), WhichEngine(EngineKind::Either), ErrorStr(nullptr),
- OptLevel(CodeGenOpt::Default), MCJMM(nullptr), RelocModel(Reloc::Default),
- CMModel(CodeModel::JITDefault), UseOrcMCJITReplacement(false) {
+ OptLevel(CodeGenOpt::Default), MemMgr(nullptr), Resolver(nullptr),
+ RelocModel(Reloc::Default), CMModel(CodeModel::JITDefault),
+ UseOrcMCJITReplacement(false) {
// IR module verification is enabled by default in debug builds, and disabled
// by default in release builds.
#ifndef NDEBUG
EngineBuilder &EngineBuilder::setMCJITMemoryManager(
std::unique_ptr<RTDyldMemoryManager> mcjmm) {
- MCJMM = std::move(mcjmm);
+ auto SharedMM = std::shared_ptr<RTDyldMemoryManager>(std::move(mcjmm));
+ MemMgr = SharedMM;
+ Resolver = SharedMM;
+ return *this;
+}
+
+EngineBuilder&
+EngineBuilder::setMemoryManager(std::unique_ptr<MCJITMemoryManager> MM) {
+ MemMgr = std::shared_ptr<MCJITMemoryManager>(std::move(MM));
+ return *this;
+}
+
+EngineBuilder&
+EngineBuilder::setSymbolResolver(std::unique_ptr<RuntimeDyld::SymbolResolver> SR) {
+ Resolver = std::shared_ptr<RuntimeDyld::SymbolResolver>(std::move(SR));
return *this;
}
// If the user specified a memory manager but didn't specify which engine to
// create, we assume they only want the JIT, and we fail if they only want
// the interpreter.
- if (MCJMM) {
+ if (MemMgr) {
if (WhichEngine & EngineKind::JIT)
WhichEngine = EngineKind::JIT;
else {
ExecutionEngine *EE = nullptr;
if (ExecutionEngine::OrcMCJITReplacementCtor && UseOrcMCJITReplacement) {
- EE = ExecutionEngine::OrcMCJITReplacementCtor(ErrorStr, std::move(MCJMM),
+ EE = ExecutionEngine::OrcMCJITReplacementCtor(ErrorStr, std::move(MemMgr),
+ std::move(Resolver),
std::move(TheTM));
EE->addModule(std::move(M));
} else if (ExecutionEngine::MCJITCtor)
- EE = ExecutionEngine::MCJITCtor(std::move(M), ErrorStr, std::move(MCJMM),
- std::move(TheTM));
+ EE = ExecutionEngine::MCJITCtor(std::move(M), ErrorStr, std::move(MemMgr),
+ std::move(Resolver), std::move(TheTM));
if (EE) {
EE->setVerifyModules(VerifyModules);
//===----------------------------------------------------------------------===//
#include "MCJIT.h"
+#include "llvm/ADT/STLExtras.h"
#include "llvm/ExecutionEngine/GenericValue.h"
#include "llvm/ExecutionEngine/JITEventListener.h"
#include "llvm/ExecutionEngine/MCJIT.h"
extern "C" void LLVMLinkInMCJIT() {
}
-ExecutionEngine *MCJIT::createJIT(std::unique_ptr<Module> M,
- std::string *ErrorStr,
- std::unique_ptr<RTDyldMemoryManager> MemMgr,
- std::unique_ptr<TargetMachine> TM) {
+ExecutionEngine*
+MCJIT::createJIT(std::unique_ptr<Module> M,
+ std::string *ErrorStr,
+ std::shared_ptr<MCJITMemoryManager> MemMgr,
+ std::shared_ptr<RuntimeDyld::SymbolResolver> Resolver,
+ std::unique_ptr<TargetMachine> TM) {
// Try to register the program as a source of symbols to resolve against.
//
// FIXME: Don't do this here.
sys::DynamicLibrary::LoadLibraryPermanently(nullptr, nullptr);
- std::unique_ptr<RTDyldMemoryManager> MM = std::move(MemMgr);
- if (!MM)
- MM = std::unique_ptr<SectionMemoryManager>(new SectionMemoryManager());
+ if (!MemMgr || !Resolver) {
+ auto RTDyldMM = std::make_shared<SectionMemoryManager>();
+ if (!MemMgr)
+ MemMgr = RTDyldMM;
+ if (!Resolver)
+ Resolver = RTDyldMM;
+ }
- return new MCJIT(std::move(M), std::move(TM), std::move(MM));
+ return new MCJIT(std::move(M), std::move(TM), std::move(MemMgr),
+ std::move(Resolver));
}
MCJIT::MCJIT(std::unique_ptr<Module> M, std::unique_ptr<TargetMachine> tm,
- std::unique_ptr<RTDyldMemoryManager> MM)
+ std::shared_ptr<MCJITMemoryManager> MemMgr,
+ std::shared_ptr<RuntimeDyld::SymbolResolver> Resolver)
: ExecutionEngine(std::move(M)), TM(std::move(tm)), Ctx(nullptr),
- MemMgr(this, std::move(MM)), Dyld(&MemMgr), ObjCache(nullptr) {
+ MemMgr(std::move(MemMgr)), Resolver(*this, std::move(Resolver)),
+ Dyld(*this->MemMgr, this->Resolver), ObjCache(nullptr) {
// FIXME: We are managing our modules, so we do not want the base class
// ExecutionEngine to manage them as well. To avoid double destruction
// of the first (and only) module added in ExecutionEngine constructor
Dyld.registerEHFrames();
// Set page permissions.
- MemMgr.finalizeMemory();
+ MemMgr->finalizeMemory();
}
// FIXME: Rename this.
finalizeLoadedModules();
}
-uint64_t MCJIT::getExistingSymbolAddress(const std::string &Name) {
+RuntimeDyld::SymbolInfo MCJIT::findExistingSymbol(const std::string &Name) {
Mangler Mang(TM->getDataLayout());
SmallString<128> FullName;
Mang.getNameWithPrefix(FullName, Name);
- return Dyld.getSymbol(FullName).getAddress();
+ return Dyld.getSymbol(FullName);
}
Module *MCJIT::findModuleForSymbol(const std::string &Name,
}
uint64_t MCJIT::getSymbolAddress(const std::string &Name,
- bool CheckFunctionsOnly)
-{
+ bool CheckFunctionsOnly) {
+ return findSymbol(Name, CheckFunctionsOnly).getAddress();
+}
+
+RuntimeDyld::SymbolInfo MCJIT::findSymbol(const std::string &Name,
+ bool CheckFunctionsOnly) {
MutexGuard locked(lock);
// First, check to see if we already have this symbol.
- uint64_t Addr = getExistingSymbolAddress(Name);
- if (Addr)
- return Addr;
+ if (auto Sym = findExistingSymbol(Name))
+ return Sym;
for (object::OwningBinary<object::Archive> &OB : Archives) {
object::Archive *A = OB.getBinary();
// This causes the object file to be loaded.
addObjectFile(std::move(OF));
// The address should be here now.
- Addr = getExistingSymbolAddress(Name);
- if (Addr)
- return Addr;
+ if (auto Sym = findExistingSymbol(Name))
+ return Sym;
}
}
}
generateCodeForModule(M);
// Check the RuntimeDyld table again, it should be there now.
- return getExistingSymbolAddress(Name);
+ return findExistingSymbol(Name);
}
// If a LazyFunctionCreator is installed, use it to get/create the function.
// FIXME: Should we instead have a LazySymbolCreator callback?
- if (LazyFunctionCreator)
- Addr = (uint64_t)LazyFunctionCreator(Name);
+ if (LazyFunctionCreator) {
+ auto Addr = static_cast<uint64_t>(
+ reinterpret_cast<uintptr_t>(LazyFunctionCreator(Name)));
+ return RuntimeDyld::SymbolInfo(Addr, JITSymbolFlags::Exported);
+ }
- return Addr;
+ return nullptr;
}
uint64_t MCJIT::getGlobalValueAddress(const std::string &Name) {
void *MCJIT::getPointerToNamedFunction(StringRef Name, bool AbortOnFailure) {
if (!isSymbolSearchingDisabled()) {
- void *ptr = MemMgr.getPointerToNamedFunction(Name, false);
+ void *ptr =
+ reinterpret_cast<void*>(
+ static_cast<uintptr_t>(Resolver.findSymbol(Name).getAddress()));
if (ptr)
return ptr;
}
void MCJIT::NotifyObjectEmitted(const object::ObjectFile& Obj,
const RuntimeDyld::LoadedObjectInfo &L) {
MutexGuard locked(lock);
- MemMgr.notifyObjectLoaded(this, Obj);
+ MemMgr->notifyObjectLoaded(this, Obj);
for (unsigned I = 0, S = EventListeners.size(); I < S; ++I) {
EventListeners[I]->NotifyObjectEmitted(Obj, L);
}
L->NotifyFreeingObject(Obj);
}
-uint64_t LinkingMemoryManager::getSymbolAddress(const std::string &Name) {
- uint64_t Result = ParentEngine->getSymbolAddress(Name, false);
+RuntimeDyld::SymbolInfo
+LinkingSymbolResolver::findSymbol(const std::string &Name) {
+ auto Result = ParentEngine.findSymbol(Name, false);
// If the symbols wasn't found and it begins with an underscore, try again
// without the underscore.
if (!Result && Name[0] == '_')
- Result = ParentEngine->getSymbolAddress(Name.substr(1), false);
+ Result = ParentEngine.findSymbol(Name.substr(1), false);
if (Result)
return Result;
- if (ParentEngine->isSymbolSearchingDisabled())
- return 0;
- return ClientMM->getSymbolAddress(Name);
+ if (ParentEngine.isSymbolSearchingDisabled())
+ return nullptr;
+ return ClientResolver->findSymbol(Name);
}
#include "llvm/ExecutionEngine/ExecutionEngine.h"
#include "llvm/ExecutionEngine/ObjectCache.h"
#include "llvm/ExecutionEngine/ObjectMemoryBuffer.h"
+#include "llvm/ExecutionEngine/RTDyldMemoryManager.h"
#include "llvm/ExecutionEngine/RuntimeDyld.h"
#include "llvm/IR/Module.h"
// functions across modules that it owns. It aggregates the memory manager
// that is passed in to the MCJIT constructor and defers most functionality
// to that object.
-class LinkingMemoryManager : public RTDyldMemoryManager {
+class LinkingSymbolResolver : public RuntimeDyld::SymbolResolver {
public:
- LinkingMemoryManager(MCJIT *Parent,
- std::unique_ptr<RTDyldMemoryManager> MM)
- : ParentEngine(Parent), ClientMM(std::move(MM)) {}
+ LinkingSymbolResolver(MCJIT &Parent,
+ std::shared_ptr<RuntimeDyld::SymbolResolver> Resolver)
+ : ParentEngine(Parent), ClientResolver(std::move(Resolver)) {}
- uint64_t getSymbolAddress(const std::string &Name) override;
+ RuntimeDyld::SymbolInfo findSymbol(const std::string &Name) override;
- // Functions deferred to client memory manager
- uint8_t *allocateCodeSection(uintptr_t Size, unsigned Alignment,
- unsigned SectionID,
- StringRef SectionName) override {
- return ClientMM->allocateCodeSection(Size, Alignment, SectionID, SectionName);
- }
-
- uint8_t *allocateDataSection(uintptr_t Size, unsigned Alignment,
- unsigned SectionID, StringRef SectionName,
- bool IsReadOnly) override {
- return ClientMM->allocateDataSection(Size, Alignment,
- SectionID, SectionName, IsReadOnly);
- }
-
- void reserveAllocationSpace(uintptr_t CodeSize, uintptr_t DataSizeRO,
- uintptr_t DataSizeRW) override {
- return ClientMM->reserveAllocationSpace(CodeSize, DataSizeRO, DataSizeRW);
- }
-
- bool needsToReserveAllocationSpace() override {
- return ClientMM->needsToReserveAllocationSpace();
- }
-
- void notifyObjectLoaded(ExecutionEngine *EE,
- const object::ObjectFile &Obj) override {
- ClientMM->notifyObjectLoaded(EE, Obj);
- }
-
- void registerEHFrames(uint8_t *Addr, uint64_t LoadAddr,
- size_t Size) override {
- ClientMM->registerEHFrames(Addr, LoadAddr, Size);
- }
-
- void deregisterEHFrames(uint8_t *Addr, uint64_t LoadAddr,
- size_t Size) override {
- ClientMM->deregisterEHFrames(Addr, LoadAddr, Size);
- }
-
- bool finalizeMemory(std::string *ErrMsg = nullptr) override {
- return ClientMM->finalizeMemory(ErrMsg);
+ // MCJIT doesn't support logical dylibs.
+ RuntimeDyld::SymbolInfo
+ findSymbolInLogicalDylib(const std::string &Name) override {
+ return nullptr;
}
private:
- MCJIT *ParentEngine;
- std::unique_ptr<RTDyldMemoryManager> ClientMM;
+ MCJIT &ParentEngine;
+ std::shared_ptr<RuntimeDyld::SymbolResolver> ClientResolver;
};
// About Module states: added->loaded->finalized.
class MCJIT : public ExecutionEngine {
MCJIT(std::unique_ptr<Module> M, std::unique_ptr<TargetMachine> tm,
- std::unique_ptr<RTDyldMemoryManager> MemMgr);
+ std::shared_ptr<MCJITMemoryManager> MemMgr,
+ std::shared_ptr<RuntimeDyld::SymbolResolver> Resolver);
typedef llvm::SmallPtrSet<Module *, 4> ModulePtrSet;
std::unique_ptr<TargetMachine> TM;
MCContext *Ctx;
- LinkingMemoryManager MemMgr;
+ std::shared_ptr<MCJITMemoryManager> MemMgr;
+ LinkingSymbolResolver Resolver;
RuntimeDyld Dyld;
std::vector<JITEventListener*> EventListeners;
MCJITCtor = createJIT;
}
- static ExecutionEngine *createJIT(std::unique_ptr<Module> M,
- std::string *ErrorStr,
- std::unique_ptr<RTDyldMemoryManager> MemMgr,
- std::unique_ptr<TargetMachine> TM);
+ static ExecutionEngine*
+ createJIT(std::unique_ptr<Module> M,
+ std::string *ErrorStr,
+ std::shared_ptr<MCJITMemoryManager> MemMgr,
+ std::shared_ptr<RuntimeDyld::SymbolResolver> Resolver,
+ std::unique_ptr<TargetMachine> TM);
// @}
+ RuntimeDyld::SymbolInfo findSymbol(const std::string &Name,
+ bool CheckFunctionsOnly);
+ // DEPRECATED - Please use findSymbol instead.
// This is not directly exposed via the ExecutionEngine API, but it is
// used by the LinkingMemoryManager.
uint64_t getSymbolAddress(const std::string &Name,
- bool CheckFunctionsOnly);
+ bool CheckFunctionsOnly);
protected:
/// emitObject -- Generate a JITed object in memory from the specified module
const RuntimeDyld::LoadedObjectInfo &L);
void NotifyFreeingObject(const object::ObjectFile& Obj);
- uint64_t getExistingSymbolAddress(const std::string &Name);
+ RuntimeDyld::SymbolInfo findExistingSymbol(const std::string &Name);
Module *findModuleForSymbol(const std::string &Name,
bool CheckFunctionsOnly);
};
class OrcMCJITReplacement : public ExecutionEngine {
- class ForwardingRTDyldMM : public RTDyldMemoryManager {
+ // OrcMCJITReplacement needs to do a little extra book-keeping to ensure that
+ // Orc's automatic finalization doesn't kick in earlier than MCJIT clients are
+ // expecting - see finalizeMemory.
+ class MCJITReplacementMemMgr : public MCJITMemoryManager {
public:
- ForwardingRTDyldMM(OrcMCJITReplacement &M) : M(M) {}
+ MCJITReplacementMemMgr(OrcMCJITReplacement &M,
+ std::shared_ptr<MCJITMemoryManager> ClientMM)
+ : M(M), ClientMM(std::move(ClientMM)) {}
uint8_t *allocateCodeSection(uintptr_t Size, unsigned Alignment,
unsigned SectionID,
StringRef SectionName) override {
uint8_t *Addr =
- M.MM->allocateCodeSection(Size, Alignment, SectionID, SectionName);
+ ClientMM->allocateCodeSection(Size, Alignment, SectionID,
+ SectionName);
M.SectionsAllocatedSinceLastLoad.insert(Addr);
return Addr;
}
uint8_t *allocateDataSection(uintptr_t Size, unsigned Alignment,
unsigned SectionID, StringRef SectionName,
bool IsReadOnly) override {
- uint8_t *Addr = M.MM->allocateDataSection(Size, Alignment, SectionID,
- SectionName, IsReadOnly);
+ uint8_t *Addr = ClientMM->allocateDataSection(Size, Alignment, SectionID,
+ SectionName, IsReadOnly);
M.SectionsAllocatedSinceLastLoad.insert(Addr);
return Addr;
}
void reserveAllocationSpace(uintptr_t CodeSize, uintptr_t DataSizeRO,
uintptr_t DataSizeRW) override {
- return M.MM->reserveAllocationSpace(CodeSize, DataSizeRO, DataSizeRW);
+ return ClientMM->reserveAllocationSpace(CodeSize, DataSizeRO,
+ DataSizeRW);
}
bool needsToReserveAllocationSpace() override {
- return M.MM->needsToReserveAllocationSpace();
+ return ClientMM->needsToReserveAllocationSpace();
}
void registerEHFrames(uint8_t *Addr, uint64_t LoadAddr,
size_t Size) override {
- return M.MM->registerEHFrames(Addr, LoadAddr, Size);
+ return ClientMM->registerEHFrames(Addr, LoadAddr, Size);
}
void deregisterEHFrames(uint8_t *Addr, uint64_t LoadAddr,
size_t Size) override {
- return M.MM->deregisterEHFrames(Addr, LoadAddr, Size);
- }
-
- uint64_t getSymbolAddress(const std::string &Name) override {
- return M.getSymbolAddressWithoutMangling(Name);
- }
-
- void *getPointerToNamedFunction(const std::string &Name,
- bool AbortOnFailure = true) override {
- return M.MM->getPointerToNamedFunction(Name, AbortOnFailure);
+ return ClientMM->deregisterEHFrames(Addr, LoadAddr, Size);
}
void notifyObjectLoaded(ExecutionEngine *EE,
const object::ObjectFile &O) override {
- return M.MM->notifyObjectLoaded(EE, O);
+ return ClientMM->notifyObjectLoaded(EE, O);
}
bool finalizeMemory(std::string *ErrMsg = nullptr) override {
// get more than one set of objects loaded but not yet finalized is if
// they were loaded during relocation of another set.
if (M.UnfinalizedSections.size() == 1)
- return M.MM->finalizeMemory(ErrMsg);
+ return ClientMM->finalizeMemory(ErrMsg);
return false;
}
+ private:
+ OrcMCJITReplacement &M;
+ std::shared_ptr<MCJITMemoryManager> ClientMM;
+ };
+
+ class LinkingResolver : public RuntimeDyld::SymbolResolver {
+ public:
+ LinkingResolver(OrcMCJITReplacement &M) : M(M) {}
+
+ RuntimeDyld::SymbolInfo findSymbol(const std::string &Name) {
+ return M.findMangledSymbol(Name);
+ }
+
+ RuntimeDyld::SymbolInfo findSymbolInLogicalDylib(const std::string &Name) {
+ return M.ClientResolver->findSymbolInLogicalDylib(Name);
+ }
+
private:
OrcMCJITReplacement &M;
};
static ExecutionEngine *
createOrcMCJITReplacement(std::string *ErrorMsg,
- std::unique_ptr<RTDyldMemoryManager> OrcJMM,
+ std::shared_ptr<MCJITMemoryManager> MemMgr,
+ std::shared_ptr<RuntimeDyld::SymbolResolver> Resolver,
std::unique_ptr<TargetMachine> TM) {
- return new OrcMCJITReplacement(std::move(OrcJMM), std::move(TM));
+ return new OrcMCJITReplacement(std::move(MemMgr), std::move(Resolver),
+ std::move(TM));
}
public:
OrcMCJITReplacementCtor = createOrcMCJITReplacement;
}
- OrcMCJITReplacement(std::unique_ptr<RTDyldMemoryManager> MM,
- std::unique_ptr<TargetMachine> TM)
- : TM(std::move(TM)), MM(std::move(MM)), Mang(this->TM->getDataLayout()),
+ OrcMCJITReplacement(
+ std::shared_ptr<MCJITMemoryManager> MemMgr,
+ std::shared_ptr<RuntimeDyld::SymbolResolver> ClientResolver,
+ std::unique_ptr<TargetMachine> TM)
+ : TM(std::move(TM)), MemMgr(*this, std::move(MemMgr)),
+ Resolver(*this), ClientResolver(std::move(ClientResolver)),
+ Mang(this->TM->getDataLayout()),
NotifyObjectLoaded(*this), NotifyFinalized(*this),
- ObjectLayer(ObjectLayerT::CreateRTDyldMMFtor(), NotifyObjectLoaded,
- NotifyFinalized),
+ ObjectLayer(NotifyObjectLoaded, NotifyFinalized),
CompileLayer(ObjectLayer, SimpleCompiler(*this->TM)),
LazyEmitLayer(CompileLayer) {
setDataLayout(this->TM->getDataLayout());
Modules.push_back(std::move(M));
std::vector<Module *> Ms;
Ms.push_back(&*Modules.back());
- LazyEmitLayer.addModuleSet(std::move(Ms),
- llvm::make_unique<ForwardingRTDyldMM>(*this));
+ LazyEmitLayer.addModuleSet(std::move(Ms), &MemMgr, &Resolver);
}
void addObjectFile(std::unique_ptr<object::ObjectFile> O) override {
std::vector<std::unique_ptr<object::ObjectFile>> Objs;
Objs.push_back(std::move(O));
- ObjectLayer.addObjectSet(std::move(Objs),
- llvm::make_unique<ForwardingRTDyldMM>(*this));
+ ObjectLayer.addObjectSet(std::move(Objs), &MemMgr, &Resolver);
}
void addObjectFile(object::OwningBinary<object::ObjectFile> O) override {
std::vector<std::unique_ptr<object::ObjectFile>> Objs;
Objs.push_back(std::move(Obj));
auto H =
- ObjectLayer.addObjectSet(std::move(Objs),
- llvm::make_unique<ForwardingRTDyldMM>(*this));
+ ObjectLayer.addObjectSet(std::move(Objs), &MemMgr, &Resolver);
std::vector<std::unique_ptr<MemoryBuffer>> Bufs;
Bufs.push_back(std::move(Buf));
}
uint64_t getSymbolAddress(StringRef Name) {
- return getSymbolAddressWithoutMangling(Mangle(Name));
+ return findSymbol(Name).getAddress();
+ }
+
+ RuntimeDyld::SymbolInfo findSymbol(StringRef Name) {
+ return findMangledSymbol(Mangle(Name));
}
void finalizeObject() override {
}
private:
- uint64_t getSymbolAddressWithoutMangling(StringRef Name) {
- if (uint64_t Addr = LazyEmitLayer.findSymbol(Name, false).getAddress())
- return Addr;
- if (uint64_t Addr = MM->getSymbolAddress(Name))
- return Addr;
- if (uint64_t Addr = scanArchives(Name))
- return Addr;
- return 0;
+ RuntimeDyld::SymbolInfo findMangledSymbol(StringRef Name) {
+ if (auto Sym = LazyEmitLayer.findSymbol(Name, false))
+ return RuntimeDyld::SymbolInfo(Sym.getAddress(), Sym.getFlags());
+ if (auto Sym = ClientResolver->findSymbol(Name))
+ return RuntimeDyld::SymbolInfo(Sym.getAddress(), Sym.getFlags());
+ if (auto Sym = scanArchives(Name))
+ return RuntimeDyld::SymbolInfo(Sym.getAddress(), Sym.getFlags());
+
+ return nullptr;
}
- uint64_t scanArchives(StringRef Name) {
+ JITSymbol scanArchives(StringRef Name) {
for (object::OwningBinary<object::Archive> &OB : Archives) {
object::Archive *A = OB.getBinary();
// Look for our symbols in each Archive
std::vector<std::unique_ptr<object::ObjectFile>> ObjSet;
ObjSet.push_back(std::unique_ptr<object::ObjectFile>(
static_cast<object::ObjectFile *>(ChildBin.release())));
- ObjectLayer.addObjectSet(
- std::move(ObjSet), llvm::make_unique<ForwardingRTDyldMM>(*this));
- if (uint64_t Addr = ObjectLayer.findSymbol(Name, true).getAddress())
- return Addr;
+ ObjectLayer.addObjectSet(std::move(ObjSet), &MemMgr, &Resolver);
+ if (auto Sym = ObjectLayer.findSymbol(Name, true))
+ return Sym;
}
}
}
- return 0;
+ return nullptr;
}
class NotifyObjectLoadedT {
assert(Objects.size() == Infos.size() &&
"Incorrect number of Infos for Objects.");
for (unsigned I = 0; I < Objects.size(); ++I)
- M.MM->notifyObjectLoaded(&M, *Objects[I]);
+ M.MemMgr.notifyObjectLoaded(&M, *Objects[I]);
};
private:
typedef LazyEmittingLayer<CompileLayerT> LazyEmitLayerT;
std::unique_ptr<TargetMachine> TM;
- std::unique_ptr<RTDyldMemoryManager> MM;
+ MCJITReplacementMemMgr MemMgr;
+ LinkingResolver Resolver;
+ std::shared_ptr<RuntimeDyld::SymbolResolver> ClientResolver;
Mangler Mang;
NotifyObjectLoadedT NotifyObjectLoaded;
// Compute the memory size required to load all sections to be loaded
// and pass this information to the memory manager
- if (MemMgr->needsToReserveAllocationSpace()) {
+ if (MemMgr.needsToReserveAllocationSpace()) {
uint64_t CodeSize = 0, DataSizeRO = 0, DataSizeRW = 0;
computeTotalAllocSize(Obj, CodeSize, DataSizeRO, DataSizeRW);
- MemMgr->reserveAllocationSpace(CodeSize, DataSizeRO, DataSizeRW);
+ MemMgr.reserveAllocationSpace(CodeSize, DataSizeRO, DataSizeRW);
}
// Used sections from the object file
// Skip common symbols already elsewhere.
if (GlobalSymbolTable.count(Name) ||
- MemMgr->getSymbolAddressInLogicalDylib(Name)) {
+ Resolver.findSymbolInLogicalDylib(Name)) {
DEBUG(dbgs() << "\tSkipping already emitted common symbol '" << Name
<< "'\n");
continue;
// Allocate memory for the section
unsigned SectionID = Sections.size();
- uint8_t *Addr = MemMgr->allocateDataSection(CommonSize, sizeof(void *),
- SectionID, StringRef(), false);
+ uint8_t *Addr = MemMgr.allocateDataSection(CommonSize, sizeof(void *),
+ SectionID, StringRef(), false);
if (!Addr)
report_fatal_error("Unable to allocate memory for common symbols!");
uint64_t Offset = 0;
if (IsRequired) {
Check(Section.getContents(data));
Allocate = DataSize + PaddingSize + StubBufSize;
- Addr = IsCode ? MemMgr->allocateCodeSection(Allocate, Alignment, SectionID,
- Name)
- : MemMgr->allocateDataSection(Allocate, Alignment, SectionID,
- Name, IsReadOnly);
+ Addr = IsCode ? MemMgr.allocateCodeSection(Allocate, Alignment, SectionID,
+ Name)
+ : MemMgr.allocateDataSection(Allocate, Alignment, SectionID,
+ Name, IsReadOnly);
if (!Addr)
report_fatal_error("Unable to allocate section memory!");
uint64_t Addr = 0;
RTDyldSymbolTable::const_iterator Loc = GlobalSymbolTable.find(Name);
if (Loc == GlobalSymbolTable.end()) {
- // This is an external symbol, try to get its address from
- // MemoryManager.
- Addr = MemMgr->getSymbolAddress(Name.data());
+ // This is an external symbol, try to get its address from the symbol
+ // resolver.
+ Addr = Resolver.findSymbol(Name.data()).getAddress();
// The call to getSymbolAddress may have caused additional modules to
// be loaded, which may have added new entries to the
// ExternalSymbolRelocations map. Consquently, we need to update our
return 0;
}
-RuntimeDyld::RuntimeDyld(RTDyldMemoryManager *mm) {
+void RuntimeDyld::MemoryManager::anchor() {}
+void RuntimeDyld::SymbolResolver::anchor() {}
+
+RuntimeDyld::RuntimeDyld(RuntimeDyld::MemoryManager &MemMgr,
+ RuntimeDyld::SymbolResolver &Resolver)
+ : MemMgr(MemMgr), Resolver(Resolver) {
// FIXME: There's a potential issue lurking here if a single instance of
// RuntimeDyld is used to load multiple objects. The current implementation
// associates a single memory manager with a RuntimeDyld instance. Even
// they share a single memory manager. This can become a problem when page
// permissions are applied.
Dyld = nullptr;
- MM = mm;
ProcessAllSections = false;
Checker = nullptr;
}
RuntimeDyld::~RuntimeDyld() {}
static std::unique_ptr<RuntimeDyldCOFF>
-createRuntimeDyldCOFF(Triple::ArchType Arch, RTDyldMemoryManager *MM,
+createRuntimeDyldCOFF(Triple::ArchType Arch, RuntimeDyld::MemoryManager &MM,
+ RuntimeDyld::SymbolResolver &Resolver,
bool ProcessAllSections, RuntimeDyldCheckerImpl *Checker) {
- std::unique_ptr<RuntimeDyldCOFF> Dyld(RuntimeDyldCOFF::create(Arch, MM));
+ std::unique_ptr<RuntimeDyldCOFF> Dyld =
+ RuntimeDyldCOFF::create(Arch, MM, Resolver);
Dyld->setProcessAllSections(ProcessAllSections);
Dyld->setRuntimeDyldChecker(Checker);
return Dyld;
}
static std::unique_ptr<RuntimeDyldELF>
-createRuntimeDyldELF(RTDyldMemoryManager *MM, bool ProcessAllSections,
- RuntimeDyldCheckerImpl *Checker) {
- std::unique_ptr<RuntimeDyldELF> Dyld(new RuntimeDyldELF(MM));
+createRuntimeDyldELF(RuntimeDyld::MemoryManager &MM,
+ RuntimeDyld::SymbolResolver &Resolver,
+ bool ProcessAllSections, RuntimeDyldCheckerImpl *Checker) {
+ std::unique_ptr<RuntimeDyldELF> Dyld(new RuntimeDyldELF(MM, Resolver));
Dyld->setProcessAllSections(ProcessAllSections);
Dyld->setRuntimeDyldChecker(Checker);
return Dyld;
}
static std::unique_ptr<RuntimeDyldMachO>
-createRuntimeDyldMachO(Triple::ArchType Arch, RTDyldMemoryManager *MM,
- bool ProcessAllSections, RuntimeDyldCheckerImpl *Checker) {
- std::unique_ptr<RuntimeDyldMachO> Dyld(RuntimeDyldMachO::create(Arch, MM));
+createRuntimeDyldMachO(Triple::ArchType Arch, RuntimeDyld::MemoryManager &MM,
+ RuntimeDyld::SymbolResolver &Resolver,
+ bool ProcessAllSections,
+ RuntimeDyldCheckerImpl *Checker) {
+ std::unique_ptr<RuntimeDyldMachO> Dyld =
+ RuntimeDyldMachO::create(Arch, MM, Resolver);
Dyld->setProcessAllSections(ProcessAllSections);
Dyld->setRuntimeDyldChecker(Checker);
return Dyld;
RuntimeDyld::loadObject(const ObjectFile &Obj) {
if (!Dyld) {
if (Obj.isELF())
- Dyld = createRuntimeDyldELF(MM, ProcessAllSections, Checker);
+ Dyld = createRuntimeDyldELF(MemMgr, Resolver, ProcessAllSections, Checker);
else if (Obj.isMachO())
Dyld = createRuntimeDyldMachO(
- static_cast<Triple::ArchType>(Obj.getArch()), MM,
+ static_cast<Triple::ArchType>(Obj.getArch()), MemMgr, Resolver,
ProcessAllSections, Checker);
else if (Obj.isCOFF())
Dyld = createRuntimeDyldCOFF(
- static_cast<Triple::ArchType>(Obj.getArch()), MM,
+ static_cast<Triple::ArchType>(Obj.getArch()), MemMgr, Resolver,
ProcessAllSections, Checker);
else
report_fatal_error("Incompatible object format!");
namespace llvm {
std::unique_ptr<RuntimeDyldCOFF>
-llvm::RuntimeDyldCOFF::create(Triple::ArchType Arch, RTDyldMemoryManager *MM) {
+llvm::RuntimeDyldCOFF::create(Triple::ArchType Arch,
+ RuntimeDyld::MemoryManager &MemMgr,
+ RuntimeDyld::SymbolResolver &Resolver) {
switch (Arch) {
default:
llvm_unreachable("Unsupported target for RuntimeDyldCOFF.");
break;
case Triple::x86_64:
- return make_unique<RuntimeDyldCOFFX86_64>(MM);
+ return make_unique<RuntimeDyldCOFFX86_64>(MemMgr, Resolver);
}
}
std::unique_ptr<RuntimeDyld::LoadedObjectInfo>
loadObject(const object::ObjectFile &Obj) override;
bool isCompatibleFile(const object::ObjectFile &Obj) const override;
- static std::unique_ptr<RuntimeDyldCOFF> create(Triple::ArchType Arch,
- RTDyldMemoryManager *MM);
+
+ static std::unique_ptr<RuntimeDyldCOFF>
+ create(Triple::ArchType Arch, RuntimeDyld::MemoryManager &MemMgr,
+ RuntimeDyld::SymbolResolver &Resolver);
protected:
- RuntimeDyldCOFF(RTDyldMemoryManager *MM) : RuntimeDyldImpl(MM) {}
+ RuntimeDyldCOFF(RuntimeDyld::MemoryManager &MemMgr,
+ RuntimeDyld::SymbolResolver &Resolver)
+ : RuntimeDyldImpl(MemMgr, Resolver) {}
uint64_t getSymbolOffset(const SymbolRef &Sym);
};
uint64_t RuntimeDyldCheckerImpl::getSymbolRemoteAddr(StringRef Symbol) const {
if (auto InternalSymbol = getRTDyld().getSymbol(Symbol))
return InternalSymbol.getAddress();
- return getRTDyld().MemMgr->getSymbolAddress(Symbol);
+ return getRTDyld().Resolver.findSymbol(Symbol).getAddress();
}
uint64_t RuntimeDyldCheckerImpl::readMemoryAtAddr(uint64_t SrcAddr,
namespace llvm {
-RuntimeDyldELF::RuntimeDyldELF(RTDyldMemoryManager *mm) : RuntimeDyldImpl(mm) {}
+RuntimeDyldELF::RuntimeDyldELF(RuntimeDyld::MemoryManager &MemMgr,
+ RuntimeDyld::SymbolResolver &Resolver)
+ : RuntimeDyldImpl(MemMgr, Resolver) {}
RuntimeDyldELF::~RuntimeDyldELF() {}
void RuntimeDyldELF::registerEHFrames() {
- if (!MemMgr)
- return;
for (int i = 0, e = UnregisteredEHFrameSections.size(); i != e; ++i) {
SID EHFrameSID = UnregisteredEHFrameSections[i];
uint8_t *EHFrameAddr = Sections[EHFrameSID].Address;
uint64_t EHFrameLoadAddr = Sections[EHFrameSID].LoadAddress;
size_t EHFrameSize = Sections[EHFrameSID].Size;
- MemMgr->registerEHFrames(EHFrameAddr, EHFrameLoadAddr, EHFrameSize);
+ MemMgr.registerEHFrames(EHFrameAddr, EHFrameLoadAddr, EHFrameSize);
RegisteredEHFrameSections.push_back(EHFrameSID);
}
UnregisteredEHFrameSections.clear();
}
void RuntimeDyldELF::deregisterEHFrames() {
- if (!MemMgr)
- return;
for (int i = 0, e = RegisteredEHFrameSections.size(); i != e; ++i) {
SID EHFrameSID = RegisteredEHFrameSections[i];
uint8_t *EHFrameAddr = Sections[EHFrameSID].Address;
uint64_t EHFrameLoadAddr = Sections[EHFrameSID].LoadAddress;
size_t EHFrameSize = Sections[EHFrameSID].Size;
- MemMgr->deregisterEHFrames(EHFrameAddr, EHFrameLoadAddr, EHFrameSize);
+ MemMgr.deregisterEHFrames(EHFrameAddr, EHFrameLoadAddr, EHFrameSize);
}
RegisteredEHFrameSections.clear();
}
void RuntimeDyldELF::finalizeLoad(const ObjectFile &Obj,
ObjSectionToIDMap &SectionMap) {
// If necessary, allocate the global offset table
- if (MemMgr) {
- // Allocate the GOT if necessary
- size_t numGOTEntries = GOTEntries.size();
- if (numGOTEntries != 0) {
- // Allocate memory for the section
- unsigned SectionID = Sections.size();
- size_t TotalSize = numGOTEntries * getGOTEntrySize();
- uint8_t *Addr = MemMgr->allocateDataSection(TotalSize, getGOTEntrySize(),
- SectionID, ".got", false);
- if (!Addr)
- report_fatal_error("Unable to allocate memory for GOT!");
-
- GOTs.push_back(std::make_pair(SectionID, GOTEntries));
- Sections.push_back(SectionEntry(".got", Addr, TotalSize, 0));
- // For now, initialize all GOT entries to zero. We'll fill them in as
- // needed when GOT-based relocations are applied.
- memset(Addr, 0, TotalSize);
- }
- } else {
- report_fatal_error("Unable to allocate memory for GOT!");
+ size_t numGOTEntries = GOTEntries.size();
+ if (numGOTEntries != 0) {
+ // Allocate memory for the section
+ unsigned SectionID = Sections.size();
+ size_t TotalSize = numGOTEntries * getGOTEntrySize();
+ uint8_t *Addr = MemMgr.allocateDataSection(TotalSize, getGOTEntrySize(),
+ SectionID, ".got", false);
+ if (!Addr)
+ report_fatal_error("Unable to allocate memory for GOT!");
+
+ GOTs.push_back(std::make_pair(SectionID, GOTEntries));
+ Sections.push_back(SectionEntry(".got", Addr, TotalSize, 0));
+ // For now, initialize all GOT entries to zero. We'll fill them in as
+ // needed when GOT-based relocations are applied.
+ memset(Addr, 0, TotalSize);
}
// Look for and record the EH frame section.
SmallVector<SID, 2> RegisteredEHFrameSections;
public:
- RuntimeDyldELF(RTDyldMemoryManager *mm);
+ RuntimeDyldELF(RuntimeDyld::MemoryManager &MemMgr,
+ RuntimeDyld::SymbolResolver &Resolver);
virtual ~RuntimeDyldELF();
std::unique_ptr<RuntimeDyld::LoadedObjectInfo>
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/Triple.h"
+#include "llvm/ExecutionEngine/RTDyldMemoryManager.h"
#include "llvm/ExecutionEngine/RuntimeDyld.h"
#include "llvm/ExecutionEngine/RuntimeDyldChecker.h"
#include "llvm/Object/ObjectFile.h"
friend class RuntimeDyldCheckerImpl;
protected:
// The MemoryManager to load objects into.
- RTDyldMemoryManager *MemMgr;
+ RuntimeDyld::MemoryManager &MemMgr;
+
+ // The symbol resolver to use for external symbols.
+ RuntimeDyld::SymbolResolver &Resolver;
// Attached RuntimeDyldChecker instance. Null if no instance attached.
RuntimeDyldCheckerImpl *Checker;
std::pair<unsigned, unsigned> loadObjectImpl(const object::ObjectFile &Obj);
public:
- RuntimeDyldImpl(RTDyldMemoryManager *mm)
- : MemMgr(mm), Checker(nullptr), ProcessAllSections(false), HasError(false) {
+ RuntimeDyldImpl(RuntimeDyld::MemoryManager &MemMgr,
+ RuntimeDyld::SymbolResolver &Resolver)
+ : MemMgr(MemMgr), Resolver(Resolver), Checker(nullptr),
+ ProcessAllSections(false), HasError(false) {
}
virtual ~RuntimeDyldImpl();
template <typename Impl>
void RuntimeDyldMachOCRTPBase<Impl>::registerEHFrames() {
- if (!MemMgr)
- return;
for (int i = 0, e = UnregisteredEHFrameSections.size(); i != e; ++i) {
EHFrameRelatedSections &SectionInfo = UnregisteredEHFrameSections[i];
if (SectionInfo.EHFrameSID == RTDYLD_INVALID_SECTION_ID ||
P = processFDE(P, DeltaForText, DeltaForEH);
} while (P != End);
- MemMgr->registerEHFrames(EHFrame->Address, EHFrame->LoadAddress,
- EHFrame->Size);
+ MemMgr.registerEHFrames(EHFrame->Address, EHFrame->LoadAddress,
+ EHFrame->Size);
}
UnregisteredEHFrameSections.clear();
}
std::unique_ptr<RuntimeDyldMachO>
-RuntimeDyldMachO::create(Triple::ArchType Arch, RTDyldMemoryManager *MM) {
+RuntimeDyldMachO::create(Triple::ArchType Arch,
+ RuntimeDyld::MemoryManager &MemMgr,
+ RuntimeDyld::SymbolResolver &Resolver) {
switch (Arch) {
default:
llvm_unreachable("Unsupported target for RuntimeDyldMachO.");
break;
- case Triple::arm: return make_unique<RuntimeDyldMachOARM>(MM);
- case Triple::aarch64: return make_unique<RuntimeDyldMachOAArch64>(MM);
- case Triple::x86: return make_unique<RuntimeDyldMachOI386>(MM);
- case Triple::x86_64: return make_unique<RuntimeDyldMachOX86_64>(MM);
+ case Triple::arm:
+ return make_unique<RuntimeDyldMachOARM>(MemMgr, Resolver);
+ case Triple::aarch64:
+ return make_unique<RuntimeDyldMachOAArch64>(MemMgr, Resolver);
+ case Triple::x86:
+ return make_unique<RuntimeDyldMachOI386>(MemMgr, Resolver);
+ case Triple::x86_64:
+ return make_unique<RuntimeDyldMachOX86_64>(MemMgr, Resolver);
}
}
// EH frame sections with the memory manager.
SmallVector<EHFrameRelatedSections, 2> UnregisteredEHFrameSections;
- RuntimeDyldMachO(RTDyldMemoryManager *mm) : RuntimeDyldImpl(mm) {}
+ RuntimeDyldMachO(RuntimeDyld::MemoryManager &MemMgr,
+ RuntimeDyld::SymbolResolver &Resolver)
+ : RuntimeDyldImpl(MemMgr, Resolver) {}
/// This convenience method uses memcpy to extract a contiguous addend (the
/// addend size and offset are taken from the corresponding fields of the RE).
public:
/// Create a RuntimeDyldMachO instance for the given target architecture.
- static std::unique_ptr<RuntimeDyldMachO> create(Triple::ArchType Arch,
- RTDyldMemoryManager *mm);
+ static std::unique_ptr<RuntimeDyldMachO>
+ create(Triple::ArchType Arch,
+ RuntimeDyld::MemoryManager &MemMgr,
+ RuntimeDyld::SymbolResolver &Resolver);
std::unique_ptr<RuntimeDyld::LoadedObjectInfo>
loadObject(const object::ObjectFile &O) override;
int64_t DeltaForEH);
public:
- RuntimeDyldMachOCRTPBase(RTDyldMemoryManager *mm) : RuntimeDyldMachO(mm) {}
+ RuntimeDyldMachOCRTPBase(RuntimeDyld::MemoryManager &MemMgr,
+ RuntimeDyld::SymbolResolver &Resolver)
+ : RuntimeDyldMachO(MemMgr, Resolver) {}
void finalizeLoad(const ObjectFile &Obj,
ObjSectionToIDMap &SectionMap) override;
SmallVector<SID, 2> RegisteredEHFrameSections;
public:
- RuntimeDyldCOFFX86_64(RTDyldMemoryManager *MM) : RuntimeDyldCOFF(MM) {}
+ RuntimeDyldCOFFX86_64(RuntimeDyld::MemoryManager &MM,
+ RuntimeDyld::SymbolResolver &Resolver)
+ : RuntimeDyldCOFF(MM, Resolver) {}
unsigned getMaxStubSize() override {
return 6; // 2-byte jmp instruction + 32-bit relative address
unsigned getStubAlignment() override { return 1; }
void registerEHFrames() override {
- if (!MemMgr)
- return;
for (auto const &EHFrameSID : UnregisteredEHFrameSections) {
uint8_t *EHFrameAddr = Sections[EHFrameSID].Address;
uint64_t EHFrameLoadAddr = Sections[EHFrameSID].LoadAddress;
size_t EHFrameSize = Sections[EHFrameSID].Size;
- MemMgr->registerEHFrames(EHFrameAddr, EHFrameLoadAddr, EHFrameSize);
+ MemMgr.registerEHFrames(EHFrameAddr, EHFrameLoadAddr, EHFrameSize);
RegisteredEHFrameSections.push_back(EHFrameSID);
}
UnregisteredEHFrameSections.clear();
typedef uint64_t TargetPtrT;
- RuntimeDyldMachOAArch64(RTDyldMemoryManager *MM)
- : RuntimeDyldMachOCRTPBase(MM) {}
+ RuntimeDyldMachOAArch64(RuntimeDyld::MemoryManager &MM,
+ RuntimeDyld::SymbolResolver &Resolver)
+ : RuntimeDyldMachOCRTPBase(MM, Resolver) {}
unsigned getMaxStubSize() override { return 8; }
typedef uint32_t TargetPtrT;
- RuntimeDyldMachOARM(RTDyldMemoryManager *MM) : RuntimeDyldMachOCRTPBase(MM) {}
+ RuntimeDyldMachOARM(RuntimeDyld::MemoryManager &MM,
+ RuntimeDyld::SymbolResolver &Resolver)
+ : RuntimeDyldMachOCRTPBase(MM, Resolver) {}
unsigned getMaxStubSize() override { return 8; }
typedef uint32_t TargetPtrT;
- RuntimeDyldMachOI386(RTDyldMemoryManager *MM)
- : RuntimeDyldMachOCRTPBase(MM) {}
+ RuntimeDyldMachOI386(RuntimeDyld::MemoryManager &MM,
+ RuntimeDyld::SymbolResolver &Resolver)
+ : RuntimeDyldMachOCRTPBase(MM, Resolver) {}
unsigned getMaxStubSize() override { return 0; }
typedef uint64_t TargetPtrT;
- RuntimeDyldMachOX86_64(RTDyldMemoryManager *MM)
- : RuntimeDyldMachOCRTPBase(MM) {}
+ RuntimeDyldMachOX86_64(RuntimeDyld::MemoryManager &MM,
+ RuntimeDyld::SymbolResolver &Resolver)
+ : RuntimeDyldMachOCRTPBase(MM, Resolver) {}
unsigned getMaxStubSize() override { return 8; }
case Triple::x86_64: {
typedef orc::JITCompileCallbackManager<CompileLayerT,
orc::OrcX86_64> CCMgrT;
- return make_unique<CCMgrT>(CompileLayer, Context, 0, 64);
+ return make_unique<CCMgrT>(CompileLayer, CCMgrMemMgr, Context, 0, 64);
}
}
}
OrcLazyJIT(std::unique_ptr<TargetMachine> TM, LLVMContext &Context)
: Error(false), TM(std::move(TM)),
Mang(this->TM->getDataLayout()),
- ObjectLayer([](){ return llvm::make_unique<SectionMemoryManager>(); }),
+ ObjectLayer(),
CompileLayer(ObjectLayer, orc::SimpleCompiler(*this->TM)),
LazyEmitLayer(CompileLayer),
CCMgr(createCallbackMgr(Triple(this->TM->getTargetTriple()), Context)),
bool Error;
std::unique_ptr<TargetMachine> TM;
Mangler Mang;
+ SectionMemoryManager CCMgrMemMgr;
ObjLayerT ObjectLayer;
CompileLayerT CompileLayer;
#include "llvm/ADT/StringMap.h"
#include "llvm/DebugInfo/DWARF/DIContext.h"
+#include "llvm/ExecutionEngine/RTDyldMemoryManager.h"
#include "llvm/ExecutionEngine/RuntimeDyld.h"
#include "llvm/ExecutionEngine/RuntimeDyldChecker.h"
#include "llvm/MC/MCAsmInfo.h"
for(unsigned i = 0, e = InputFileList.size(); i != e; ++i) {
// Instantiate a dynamic linker.
TrivialMemoryManager MemMgr;
- RuntimeDyld Dyld(&MemMgr);
+ RuntimeDyld Dyld(MemMgr, MemMgr);
// Load the input memory buffer.
// Instantiate a dynamic linker.
TrivialMemoryManager MemMgr;
- RuntimeDyld Dyld(&MemMgr);
+ RuntimeDyld Dyld(MemMgr, MemMgr);
// If we don't have any input files, read from stdin.
if (!InputFileList.size())
// Instantiate a dynamic linker.
TrivialMemoryManager MemMgr;
- RuntimeDyld Dyld(&MemMgr);
+ RuntimeDyld Dyld(MemMgr, MemMgr);
Dyld.setProcessAllSections(true);
RuntimeDyldChecker Checker(Dyld, Disassembler.get(), InstPrinter.get(),
llvm::dbgs());
struct MockBaseLayer {
typedef int ModuleSetHandleT;
- ModuleSetHandleT addModuleSet(std::list<std::unique_ptr<llvm::Module>>,
- std::unique_ptr<llvm::RTDyldMemoryManager> x) {
- EXPECT_FALSE(x);
+ ModuleSetHandleT addModuleSet(
+ std::list<std::unique_ptr<llvm::Module>>,
+ std::unique_ptr<llvm::RuntimeDyld::MemoryManager> MemMgr,
+ std::unique_ptr<llvm::RuntimeDyld::SymbolResolver> Resolver) {
+ EXPECT_FALSE(MemMgr);
return 42;
}
};
TEST(LazyEmittingLayerTest, Empty) {
MockBaseLayer M;
llvm::orc::LazyEmittingLayer<MockBaseLayer> L(M);
- L.addModuleSet(std::list<std::unique_ptr<llvm::Module>>(), nullptr);
+ L.addModuleSet(std::list<std::unique_ptr<llvm::Module>>(), nullptr, nullptr);
}
}