diff options
Diffstat (limited to 'include/llvm/ExecutionEngine')
-rw-r--r-- | include/llvm/ExecutionEngine/ExecutionEngine.h | 3 | ||||
-rw-r--r-- | include/llvm/ExecutionEngine/JITSymbolFlags.h | 81 | ||||
-rw-r--r-- | include/llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h | 17 | ||||
-rw-r--r-- | include/llvm/ExecutionEngine/Orc/IndirectionUtils.h | 109 | ||||
-rw-r--r-- | include/llvm/ExecutionEngine/Orc/JITSymbol.h | 19 | ||||
-rw-r--r-- | include/llvm/ExecutionEngine/Orc/LazyEmittingLayer.h | 116 | ||||
-rw-r--r-- | include/llvm/ExecutionEngine/Orc/ObjectLinkingLayer.h | 50 | ||||
-rw-r--r-- | include/llvm/ExecutionEngine/Orc/OrcTargetSupport.h | 7 | ||||
-rw-r--r-- | include/llvm/ExecutionEngine/RuntimeDyld.h | 27 | ||||
-rw-r--r-- | include/llvm/ExecutionEngine/RuntimeDyldChecker.h | 6 |
10 files changed, 266 insertions, 169 deletions
diff --git a/include/llvm/ExecutionEngine/ExecutionEngine.h b/include/llvm/ExecutionEngine/ExecutionEngine.h index 17de5c7..abdaa0c 100644 --- a/include/llvm/ExecutionEngine/ExecutionEngine.h +++ b/include/llvm/ExecutionEngine/ExecutionEngine.h @@ -510,9 +510,6 @@ private: bool VerifyModules; bool UseOrcMCJITReplacement; - /// InitEngine - Does the common initialization of default options. - void InitEngine(); - public: /// Default constructor for EngineBuilder. EngineBuilder(); diff --git a/include/llvm/ExecutionEngine/JITSymbolFlags.h b/include/llvm/ExecutionEngine/JITSymbolFlags.h new file mode 100644 index 0000000..450e948 --- /dev/null +++ b/include/llvm/ExecutionEngine/JITSymbolFlags.h @@ -0,0 +1,81 @@ +//===------ JITSymbolFlags.h - Flags for symbols in the JIT -----*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Symbol flags for symbols in the JIT (e.g. weak, exported). +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_EXECUTIONENGINE_JITSYMBOLFLAGS_H +#define LLVM_EXECUTIONENGINE_JITSYMBOLFLAGS_H + +#include "llvm/IR/GlobalValue.h" + +namespace llvm { + +/// @brief Flags for symbols in the JIT. +enum class JITSymbolFlags : char { + None = 0, + Weak = 1U << 0, + Exported = 1U << 1 +}; + +inline JITSymbolFlags operator|(JITSymbolFlags LHS, JITSymbolFlags RHS) { + typedef std::underlying_type<JITSymbolFlags>::type UT; + return static_cast<JITSymbolFlags>( + static_cast<UT>(LHS) | static_cast<UT>(RHS)); +} + +inline JITSymbolFlags& operator |=(JITSymbolFlags &LHS, JITSymbolFlags RHS) { + LHS = LHS | RHS; + return LHS; +} + +inline JITSymbolFlags operator&(JITSymbolFlags LHS, JITSymbolFlags RHS) { + typedef std::underlying_type<JITSymbolFlags>::type UT; + return static_cast<JITSymbolFlags>( + static_cast<UT>(LHS) & static_cast<UT>(RHS)); +} + +inline JITSymbolFlags& operator &=(JITSymbolFlags &LHS, JITSymbolFlags RHS) { + LHS = LHS & RHS; + return LHS; +} + +/// @brief Base class for symbols in the JIT. +class JITSymbolBase { +public: + JITSymbolBase(JITSymbolFlags Flags) : Flags(Flags) {} + + JITSymbolFlags getFlags() const { return Flags; } + + bool isWeak() const { + return (Flags & JITSymbolFlags::Weak) == JITSymbolFlags::Weak; + } + + bool isExported() const { + return (Flags & JITSymbolFlags::Exported) == JITSymbolFlags::Exported; + } + + static JITSymbolFlags flagsFromGlobalValue(const GlobalValue &GV) { + JITSymbolFlags Flags = JITSymbolFlags::None; + if (GV.hasWeakLinkage()) + Flags |= JITSymbolFlags::Weak; + if (!GV.hasLocalLinkage() && !GV.hasHiddenVisibility()) + Flags |= JITSymbolFlags::Exported; + return Flags; + + } + +private: + JITSymbolFlags Flags; +}; + +} // end namespace llvm + +#endif diff --git a/include/llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h b/include/llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h index 0e218e2..77b0c48 100644 --- a/include/llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h +++ b/include/llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h @@ -142,9 +142,8 @@ public: typedef std::function<uint64_t(const std::string &)> LookupFtor; /// @brief Construct a compile-on-demand layer instance. - CompileOnDemandLayer(BaseLayerT &BaseLayer, LLVMContext &Context) - : BaseLayer(BaseLayer), - CompileCallbackMgr(BaseLayer, Context, 0, 64) {} + CompileOnDemandLayer(BaseLayerT &BaseLayer, CompileCallbackMgrT &CallbackMgr) + : BaseLayer(BaseLayer), CompileCallbackMgr(CallbackMgr) {} /// @brief Add a module to the compile-on-demand layer. template <typename ModuleSetT> @@ -194,8 +193,8 @@ public: /// below this one. JITSymbol findSymbolIn(ModuleSetHandleT H, const std::string &Name, bool ExportedSymbolsOnly) { - BaseLayerModuleSetHandleListT &BaseLayerHandles = H->second; - for (auto &BH : BaseLayerHandles) { + + for (auto &BH : H->BaseLayerModuleSetHandles) { if (auto Symbol = BaseLayer.findSymbolIn(BH, Name, ExportedSymbolsOnly)) return Symbol; } @@ -274,7 +273,7 @@ private: // Set the compile actions for this module: for (auto &KVPair : NewStubInfos) { std::string BodyName = Mangle(KVPair->first + BodySuffix, - *M.getDataLayout()); + M.getDataLayout()); auto &CCInfo = KVPair->second; CCInfo.setCompileAction( [=](){ @@ -291,10 +290,10 @@ private: for (auto &KVPair : StubInfos) { std::string AddrName = Mangle(KVPair.first + AddrSuffix, - *M.getDataLayout()); + M.getDataLayout()); auto &CCInfo = KVPair.second; CCInfo.setUpdateAction( - CompileCallbackMgr.getLocalFPUpdater(StubsH, AddrName)); + getLocalFPUpdater(BaseLayer, StubsH, AddrName)); } } @@ -345,7 +344,7 @@ private: } BaseLayerT &BaseLayer; - CompileCallbackMgrT CompileCallbackMgr; + CompileCallbackMgrT &CompileCallbackMgr; ModuleSetInfoListT ModuleSetInfos; }; diff --git a/include/llvm/ExecutionEngine/Orc/IndirectionUtils.h b/include/llvm/ExecutionEngine/Orc/IndirectionUtils.h index e9d3d34..8ce1d4d 100644 --- a/include/llvm/ExecutionEngine/Orc/IndirectionUtils.h +++ b/include/llvm/ExecutionEngine/Orc/IndirectionUtils.h @@ -26,10 +26,34 @@ namespace orc { /// @brief Base class for JITLayer independent aspects of /// JITCompileCallbackManager. -template <typename TargetT> class JITCompileCallbackManagerBase { public: + typedef std::function<TargetAddress()> CompileFtor; + typedef std::function<void(TargetAddress)> UpdateFtor; + + /// @brief Handle to a newly created compile callback. Can be used to get an + /// IR constant representing the address of the trampoline, and to set + /// the compile and update actions for the callback. + class CompileCallbackInfo { + public: + CompileCallbackInfo(Constant *Addr, CompileFtor &Compile, + UpdateFtor &Update) + : Addr(Addr), Compile(Compile), Update(Update) {} + + Constant* getAddress() const { return Addr; } + void setCompileAction(CompileFtor Compile) { + this->Compile = std::move(Compile); + } + void setUpdateAction(UpdateFtor Update) { + this->Update = std::move(Update); + } + private: + Constant *Addr; + CompileFtor &Compile; + UpdateFtor &Update; + }; + /// @brief Construct a JITCompileCallbackManagerBase. /// @param ErrorHandlerAddress The address of an error handler in the target /// process to be used if a compile callback fails. @@ -41,10 +65,12 @@ public: : ErrorHandlerAddress(ErrorHandlerAddress), NumTrampolinesPerBlock(NumTrampolinesPerBlock) {} + virtual ~JITCompileCallbackManagerBase() {} + /// @brief Execute the callback for the given trampoline id. Called by the JIT /// to compile functions on demand. TargetAddress executeCompileCallback(TargetAddress TrampolineID) { - typename TrampolineMapT::iterator I = ActiveTrampolines.find(TrampolineID); + TrampolineMapT::iterator I = ActiveTrampolines.find(TrampolineID); // FIXME: Also raise an error in the Orc error-handler when we finally have // one. if (I == ActiveTrampolines.end()) @@ -56,7 +82,7 @@ public: // Moving the trampoline ID back to the available list first means there's at // least one available trampoline if the compile action triggers a request for // a new one. - AvailableTrampolines.push_back(I->first - TargetT::CallSize); + AvailableTrampolines.push_back(I->first); auto CallbackHandler = std::move(I->second); ActiveTrampolines.erase(I); @@ -67,14 +93,14 @@ public: return ErrorHandlerAddress; } -protected: + /// @brief Get/create a compile callback with the given signature. + virtual CompileCallbackInfo getCompileCallback(FunctionType &FT) = 0; - typedef std::function<TargetAddress()> CompileFtorT; - typedef std::function<void(TargetAddress)> UpdateFtorT; +protected: struct CallbackHandler { - CompileFtorT Compile; - UpdateFtorT Update; + CompileFtor Compile; + UpdateFtor Update; }; TargetAddress ErrorHandlerAddress; @@ -87,15 +113,9 @@ protected: /// @brief Manage compile callbacks. template <typename JITLayerT, typename TargetT> -class JITCompileCallbackManager : - public JITCompileCallbackManagerBase<TargetT> { +class JITCompileCallbackManager : public JITCompileCallbackManagerBase { public: - typedef typename JITCompileCallbackManagerBase<TargetT>::CompileFtorT - CompileFtorT; - typedef typename JITCompileCallbackManagerBase<TargetT>::UpdateFtorT - UpdateFtorT; - /// @brief Construct a JITCompileCallbackManager. /// @param JIT JIT layer to emit callback trampolines, etc. into. /// @param Context LLVMContext to use for trampoline & resolve block modules. @@ -108,39 +128,17 @@ public: JITCompileCallbackManager(JITLayerT &JIT, LLVMContext &Context, TargetAddress ErrorHandlerAddress, unsigned NumTrampolinesPerBlock) - : JITCompileCallbackManagerBase<TargetT>(ErrorHandlerAddress, - NumTrampolinesPerBlock), + : JITCompileCallbackManagerBase(ErrorHandlerAddress, + NumTrampolinesPerBlock), JIT(JIT) { emitResolverBlock(Context); } - /// @brief Handle to a newly created compile callback. Can be used to get an - /// IR constant representing the address of the trampoline, and to set - /// the compile and update actions for the callback. - class CompileCallbackInfo { - public: - CompileCallbackInfo(Constant *Addr, CompileFtorT &Compile, - UpdateFtorT &Update) - : Addr(Addr), Compile(Compile), Update(Update) {} - - Constant* getAddress() const { return Addr; } - void setCompileAction(CompileFtorT Compile) { - this->Compile = std::move(Compile); - } - void setUpdateAction(UpdateFtorT Update) { - this->Update = std::move(Update); - } - private: - Constant *Addr; - CompileFtorT &Compile; - UpdateFtorT &Update; - }; - /// @brief Get/create a compile callback with the given signature. - CompileCallbackInfo getCompileCallback(FunctionType &FT) { + CompileCallbackInfo getCompileCallback(FunctionType &FT) final { TargetAddress TrampolineAddr = getAvailableTrampolineAddr(FT.getContext()); auto &CallbackHandler = - this->ActiveTrampolines[TrampolineAddr + TargetT::CallSize]; + this->ActiveTrampolines[TrampolineAddr]; Constant *AddrIntVal = ConstantInt::get(Type::getInt64Ty(FT.getContext()), TrampolineAddr); Constant *AddrPtrVal = @@ -151,19 +149,6 @@ public: CallbackHandler.Update); } - /// @brief Get a functor for updating the value of a named function pointer. - UpdateFtorT getLocalFPUpdater(typename JITLayerT::ModuleSetHandleT H, - std::string Name) { - // FIXME: Move-capture Name once we can use C++14. - return [=](TargetAddress Addr) { - auto FPSym = JIT.findSymbolIn(H, Name, true); - assert(FPSym && "Cannot find function pointer to update."); - void *FPAddr = reinterpret_cast<void*>( - static_cast<uintptr_t>(FPSym.getAddress())); - memcpy(FPAddr, &Addr, sizeof(uintptr_t)); - }; - } - private: std::vector<std::unique_ptr<Module>> @@ -216,6 +201,22 @@ private: TargetAddress ResolverBlockAddr; }; +/// @brief Get an update functor for updating the value of a named function +/// pointer. +template <typename JITLayerT> +JITCompileCallbackManagerBase::UpdateFtor +getLocalFPUpdater(JITLayerT &JIT, typename JITLayerT::ModuleSetHandleT H, + std::string Name) { + // FIXME: Move-capture Name once we can use C++14. + return [=,&JIT](TargetAddress Addr) { + auto FPSym = JIT.findSymbolIn(H, Name, true); + assert(FPSym && "Cannot find function pointer to update."); + void *FPAddr = reinterpret_cast<void*>( + static_cast<uintptr_t>(FPSym.getAddress())); + memcpy(FPAddr, &Addr, sizeof(uintptr_t)); + }; + } + GlobalVariable* createImplPointer(Function &F, const Twine &Name, Constant *Initializer); diff --git a/include/llvm/ExecutionEngine/Orc/JITSymbol.h b/include/llvm/ExecutionEngine/Orc/JITSymbol.h index a670222..7c3ad56 100644 --- a/include/llvm/ExecutionEngine/Orc/JITSymbol.h +++ b/include/llvm/ExecutionEngine/Orc/JITSymbol.h @@ -14,6 +14,7 @@ #ifndef LLVM_EXECUTIONENGINE_ORC_JITSYMBOL_H #define LLVM_EXECUTIONENGINE_ORC_JITSYMBOL_H +#include "llvm/ExecutionEngine/JITSymbolFlags.h" #include "llvm/Support/DataTypes.h" #include <cassert> #include <functional> @@ -25,17 +26,19 @@ namespace orc { typedef uint64_t TargetAddress; /// @brief Represents a symbol in the JIT. -class JITSymbol { -public: +class JITSymbol : public JITSymbolBase { +public: + typedef std::function<TargetAddress()> GetAddressFtor; /// @brief Create a 'null' symbol that represents failure to find a symbol /// definition. - JITSymbol(std::nullptr_t) : CachedAddr(0) {} + JITSymbol(std::nullptr_t) + : JITSymbolBase(JITSymbolFlags::None), CachedAddr(0) {} /// @brief Create a symbol for a definition with a known address. - JITSymbol(TargetAddress Addr) - : CachedAddr(Addr) {} + JITSymbol(TargetAddress Addr, JITSymbolFlags Flags) + : JITSymbolBase(Flags), CachedAddr(Addr) {} /// @brief Create a symbol for a definition that doesn't have a known address /// yet. @@ -46,8 +49,8 @@ public: /// definition without actually materializing the definition up front. The /// user can materialize the definition at any time by calling the getAddress /// method. - JITSymbol(GetAddressFtor GetAddress) - : CachedAddr(0), GetAddress(std::move(GetAddress)) {} + JITSymbol(GetAddressFtor GetAddress, JITSymbolFlags Flags) + : JITSymbolBase(Flags), GetAddress(std::move(GetAddress)), CachedAddr(0) {} /// @brief Returns true if the symbol exists, false otherwise. explicit operator bool() const { return CachedAddr || GetAddress; } @@ -64,8 +67,8 @@ public: } private: - TargetAddress CachedAddr; GetAddressFtor GetAddress; + TargetAddress CachedAddr; }; } // End namespace orc. diff --git a/include/llvm/ExecutionEngine/Orc/LazyEmittingLayer.h b/include/llvm/ExecutionEngine/Orc/LazyEmittingLayer.h index 2a94abe..ac5fccf 100644 --- a/include/llvm/ExecutionEngine/Orc/LazyEmittingLayer.h +++ b/include/llvm/ExecutionEngine/Orc/LazyEmittingLayer.h @@ -45,23 +45,25 @@ private: JITSymbol find(StringRef Name, bool ExportedSymbolsOnly, BaseLayerT &B) { switch (EmitState) { case NotEmitted: - if (provides(Name, ExportedSymbolsOnly)) { + if (auto GV = searchGVs(Name, ExportedSymbolsOnly)) { // Create a std::string version of Name to capture here - the argument // (a StringRef) may go away before the lambda is executed. - // FIXME: Use capture-init when we move to C++14. + // FIXME: Use capture-init when we move to C++14. std::string PName = Name; - return JITSymbol( - [this, ExportedSymbolsOnly, PName, &B]() -> TargetAddress { - if (this->EmitState == Emitting) - return 0; - else if (this->EmitState == NotEmitted) { - this->EmitState = Emitting; - Handle = this->emitToBaseLayer(B); - this->EmitState = Emitted; - } - return B.findSymbolIn(Handle, PName, ExportedSymbolsOnly) - .getAddress(); - }); + JITSymbolFlags Flags = JITSymbolBase::flagsFromGlobalValue(*GV); + auto GetAddress = + [this, ExportedSymbolsOnly, PName, &B]() -> TargetAddress { + if (this->EmitState == Emitting) + return 0; + else if (this->EmitState == NotEmitted) { + this->EmitState = Emitting; + Handle = this->emitToBaseLayer(B); + this->EmitState = Emitted; + } + auto Sym = B.findSymbolIn(Handle, PName, ExportedSymbolsOnly); + return Sym.getAddress(); + }; + return JITSymbol(std::move(GetAddress), Flags); } else return nullptr; case Emitting: @@ -98,7 +100,8 @@ private: std::unique_ptr<RTDyldMemoryManager> MM); protected: - virtual bool provides(StringRef Name, bool ExportedSymbolsOnly) const = 0; + virtual const GlobalValue* searchGVs(StringRef Name, + bool ExportedSymbolsOnly) const = 0; virtual BaseLayerHandleT emitToBaseLayer(BaseLayerT &BaseLayer) = 0; private: @@ -115,46 +118,48 @@ private: protected: - BaseLayerHandleT emitToBaseLayer(BaseLayerT &BaseLayer) override { - // 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. - MangledNames.reset(); - return BaseLayer.addModuleSet(std::move(Ms), std::move(MM)); - } - - bool provides(StringRef Name, bool ExportedSymbolsOnly) const override { + const GlobalValue* searchGVs(StringRef Name, + bool ExportedSymbolsOnly) const override { // FIXME: We could clean all this up if we had a way to reliably demangle // names: We could just demangle name and search, rather than // mangling everything else. // If we have already built the mangled name set then just search it. - if (MangledNames) { - auto VI = MangledNames->find(Name); - if (VI == MangledNames->end()) - return false; - return !ExportedSymbolsOnly || VI->second; + if (MangledSymbols) { + auto VI = MangledSymbols->find(Name); + if (VI == MangledSymbols->end()) + return nullptr; + auto GV = VI->second; + if (!ExportedSymbolsOnly || GV->hasDefaultVisibility()) + return GV; + return nullptr; } // If we haven't built the mangled name set yet, try to build it. As an // optimization this will leave MangledNames set to nullptr if we find // Name in the process of building the set. - buildMangledNames(Name, ExportedSymbolsOnly); - if (!MangledNames) - return true; - return false; + return buildMangledSymbols(Name, ExportedSymbolsOnly); + } + + BaseLayerHandleT emitToBaseLayer(BaseLayerT &BaseLayer) override { + // 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)); } private: // If the mangled name of the given GlobalValue matches the given search // name (and its visibility conforms to the ExportedSymbolsOnly flag) then - // just return 'true'. Otherwise, add the mangled name to the Names map and - // return 'false'. - bool addGlobalValue(StringMap<bool> &Names, const GlobalValue &GV, - const Mangler &Mang, StringRef SearchName, - bool ExportedSymbolsOnly) const { + // return the symbol. Otherwise, add the mangled name to the Names map and + // return nullptr. + const GlobalValue* addGlobalValue(StringMap<const GlobalValue*> &Names, + const GlobalValue &GV, + const Mangler &Mang, StringRef SearchName, + bool ExportedSymbolsOnly) const { // Modules don't "provide" decls or common symbols. if (GV.isDeclaration() || GV.hasCommonLinkage()) - return false; + return nullptr; // Mangle the GV name. std::string MangledName; @@ -167,39 +172,42 @@ private: // bail out early. if (MangledName == SearchName) if (!ExportedSymbolsOnly || GV.hasDefaultVisibility()) - return true; + return &GV; // Otherwise add this to the map for later. - Names[MangledName] = GV.hasDefaultVisibility(); - return false; + Names[MangledName] = &GV; + return nullptr; } - // Build the MangledNames map. Bails out early (with MangledNames left set + // Build the MangledSymbols map. Bails out early (with MangledSymbols left set // to nullptr) if the given SearchName is found while building the map. - void buildMangledNames(StringRef SearchName, - bool ExportedSymbolsOnly) const { - assert(!MangledNames && "Mangled names map already exists?"); + const GlobalValue* buildMangledSymbols(StringRef SearchName, + bool ExportedSymbolsOnly) const { + assert(!MangledSymbols && "Mangled symbols map already exists?"); - auto Names = llvm::make_unique<StringMap<bool>>(); + auto Symbols = llvm::make_unique<StringMap<const GlobalValue*>>(); for (const auto &M : Ms) { - Mangler Mang(M->getDataLayout()); + Mangler Mang(&M->getDataLayout()); - for (const auto &GV : M->globals()) - if (addGlobalValue(*Names, GV, Mang, SearchName, ExportedSymbolsOnly)) - return; + for (const auto &V : M->globals()) + if (auto GV = addGlobalValue(*Symbols, V, Mang, SearchName, + ExportedSymbolsOnly)) + return GV; for (const auto &F : *M) - if (addGlobalValue(*Names, F, Mang, SearchName, ExportedSymbolsOnly)) - return; + if (auto GV = addGlobalValue(*Symbols, F, Mang, SearchName, + ExportedSymbolsOnly)) + return GV; } - MangledNames = std::move(Names); + MangledSymbols = std::move(Symbols); + return nullptr; } ModuleSetT Ms; std::unique_ptr<RTDyldMemoryManager> MM; - mutable std::unique_ptr<StringMap<bool>> MangledNames; + mutable std::unique_ptr<StringMap<const GlobalValue*>> MangledSymbols; }; typedef std::list<std::unique_ptr<EmissionDeferredSet>> ModuleSetListT; diff --git a/include/llvm/ExecutionEngine/Orc/ObjectLinkingLayer.h b/include/llvm/ExecutionEngine/Orc/ObjectLinkingLayer.h index 36af0fe..9838991 100644 --- a/include/llvm/ExecutionEngine/Orc/ObjectLinkingLayer.h +++ b/include/llvm/ExecutionEngine/Orc/ObjectLinkingLayer.h @@ -51,10 +51,8 @@ protected: return RTDyld->loadObject(Obj); } - TargetAddress getSymbolAddress(StringRef Name, bool ExportedSymbolsOnly) { - if (ExportedSymbolsOnly) - return RTDyld->getExportedSymbolLoadAddress(Name); - return RTDyld->getSymbolLoadAddress(Name); + RuntimeDyld::SymbolInfo getSymbol(StringRef Name) const { + return RTDyld->getSymbol(Name); } bool NeedsFinalization() const { return (State == Raw); } @@ -214,28 +212,32 @@ public: /// given object set. JITSymbol findSymbolIn(ObjSetHandleT H, StringRef Name, bool ExportedSymbolsOnly) { - if (auto Addr = H->getSymbolAddress(Name, ExportedSymbolsOnly)) { - if (!H->NeedsFinalization()) { - // If this instance has already been finalized then we can just return - // the address. - return JITSymbol(Addr); - } else { - // If this instance needs finalization return a functor that will do it. - // The functor still needs to double-check whether finalization is - // required, in case someone else finalizes this set before the functor - // is called. - return JITSymbol( - [this, Addr, H]() { - if (H->NeedsFinalization()) { - H->Finalize(); - if (NotifyFinalized) - NotifyFinalized(H); - } - return Addr; - }); + if (auto Sym = H->getSymbol(Name)) { + if (Sym.isExported() || !ExportedSymbolsOnly) { + auto Addr = Sym.getAddress(); + auto Flags = Sym.getFlags(); + if (!H->NeedsFinalization()) { + // If this instance has already been finalized then we can just return + // the address. + return JITSymbol(Addr, Flags); + } else { + // If this instance needs finalization return a functor that will do + // 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 = + [this, Addr, H]() { + if (H->NeedsFinalization()) { + H->Finalize(); + if (NotifyFinalized) + NotifyFinalized(H); + } + return Addr; + }; + return JITSymbol(std::move(GetAddress), Flags); + } } } - return nullptr; } diff --git a/include/llvm/ExecutionEngine/Orc/OrcTargetSupport.h b/include/llvm/ExecutionEngine/Orc/OrcTargetSupport.h index c6f866a..309f5a9 100644 --- a/include/llvm/ExecutionEngine/Orc/OrcTargetSupport.h +++ b/include/llvm/ExecutionEngine/Orc/OrcTargetSupport.h @@ -25,15 +25,12 @@ public: /// @brief Insert module-level inline callback asm into module M for the /// symbols managed by JITResolveCallbackHandler J. - static void insertResolverBlock( - Module &M, - JITCompileCallbackManagerBase<OrcX86_64> &JCBM); + static void insertResolverBlock(Module &M, + JITCompileCallbackManagerBase &JCBM); /// @brief Get a label name from the given index. typedef std::function<std::string(unsigned)> LabelNameFtor; - static const unsigned CallSize = 6; - /// @brief Insert the requested number of trampolines into the given module. /// @param M Module to insert the call block into. /// @param NumCalls Number of calls to create in the call block. diff --git a/include/llvm/ExecutionEngine/RuntimeDyld.h b/include/llvm/ExecutionEngine/RuntimeDyld.h index 08cfa39..fe0ccda 100644 --- a/include/llvm/ExecutionEngine/RuntimeDyld.h +++ b/include/llvm/ExecutionEngine/RuntimeDyld.h @@ -14,6 +14,7 @@ #ifndef LLVM_EXECUTIONENGINE_RUNTIMEDYLD_H #define LLVM_EXECUTIONENGINE_RUNTIMEDYLD_H +#include "JITSymbolFlags.h" #include "llvm/ADT/StringRef.h" #include "llvm/ExecutionEngine/RTDyldMemoryManager.h" #include "llvm/Support/Memory.h" @@ -28,7 +29,7 @@ namespace object { class RuntimeDyldImpl; class RuntimeDyldCheckerImpl; - + class RuntimeDyld { friend class RuntimeDyldCheckerImpl; @@ -47,6 +48,18 @@ protected: void reassignSectionAddress(unsigned SectionID, uint64_t Addr); public: + /// \brief Information about a named symbol. + class SymbolInfo : public JITSymbolBase { + public: + SymbolInfo(std::nullptr_t) : JITSymbolBase(JITSymbolFlags::None), Address(0) {} + SymbolInfo(uint64_t Address, JITSymbolFlags Flags) + : JITSymbolBase(Flags), Address(Address) {} + explicit operator bool() const { return Address != 0; } + uint64_t getAddress() const { return Address; } + private: + uint64_t Address; + }; + /// \brief Information about the loaded object. class LoadedObjectInfo { friend class RuntimeDyldImpl; @@ -79,15 +92,11 @@ public: /// Get the address of our local copy of the symbol. This may or may not /// be the address used for relocation (clients can copy the data around /// and resolve relocatons based on where they put it). - void *getSymbolAddress(StringRef Name) const; - - /// Get the address of the target copy of the symbol (works for both exported - /// and non-exported symbols). This is the address used for relocation. - uint64_t getSymbolLoadAddress(StringRef Name) const; + void *getSymbolLocalAddress(StringRef Name) const; - /// Get the address of the target copy of the symbol (works for exported - /// symbols only). This is the address used for relocation. - uint64_t getExportedSymbolLoadAddress(StringRef Name) const; + /// Get the target address and flags for the named symbol. + /// This address is the one used for relocation. + SymbolInfo getSymbol(StringRef Name) const; /// Resolve the relocations for all symbols we currently know about. void resolveRelocations(); diff --git a/include/llvm/ExecutionEngine/RuntimeDyldChecker.h b/include/llvm/ExecutionEngine/RuntimeDyldChecker.h index 23936a6..31ce151 100644 --- a/include/llvm/ExecutionEngine/RuntimeDyldChecker.h +++ b/include/llvm/ExecutionEngine/RuntimeDyldChecker.h @@ -86,12 +86,12 @@ public: /// \brief Returns the address of the requested section (or an error message /// in the second element of the pair if the address cannot be found). /// - /// if 'LinkerAddress' is true, this returns the address of the section - /// within the linker's memory. If 'LinkerAddress' is false it returns the + /// if 'LocalAddress' is true, this returns the address of the section + /// within the linker's memory. If 'LocalAddress' is false it returns the /// address within the target process (i.e. the load address). std::pair<uint64_t, std::string> getSectionAddr(StringRef FileName, StringRef SectionName, - bool LinkerAddress); + bool LocalAddress); private: std::unique_ptr<RuntimeDyldCheckerImpl> Impl; |