1 //===--- LogicalDylib.h - Simulates dylib-style symbol lookup ---*- C++ -*-===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // Simulates symbol resolution inside a dylib. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #ifndef LLVM_EXECUTIONENGINE_ORC_LOGICALDYLIB_H 15 #define LLVM_EXECUTIONENGINE_ORC_LOGICALDYLIB_H 16 17 #include "llvm/ExecutionEngine/Orc/JITSymbol.h" 18 #include <string> 19 #include <vector> 20 21 namespace llvm { 22 namespace orc { 23 24 template <typename BaseLayerT, 25 typename LogicalModuleResources, 26 typename LogicalDylibResources> 27 class LogicalDylib { 28 public: 29 typedef typename BaseLayerT::ModuleSetHandleT BaseLayerModuleSetHandleT; 30 private: 31 32 typedef std::vector<BaseLayerModuleSetHandleT> BaseLayerHandleList; 33 34 struct LogicalModule { 35 // Make this move-only to ensure they don't get duplicated across moves of 36 // LogicalDylib or anything like that. LogicalModuleLogicalModule37 LogicalModule(LogicalModule &&RHS) 38 : Resources(std::move(RHS.Resources)), 39 BaseLayerHandles(std::move(RHS.BaseLayerHandles)) {} 40 LogicalModule() = default; 41 LogicalModuleResources Resources; 42 BaseLayerHandleList BaseLayerHandles; 43 }; 44 typedef std::vector<LogicalModule> LogicalModuleList; 45 46 public: 47 48 typedef typename BaseLayerHandleList::iterator BaseLayerHandleIterator; 49 typedef typename LogicalModuleList::iterator LogicalModuleHandle; 50 LogicalDylib(BaseLayerT & BaseLayer)51 LogicalDylib(BaseLayerT &BaseLayer) : BaseLayer(BaseLayer) {} 52 ~LogicalDylib()53 ~LogicalDylib() { 54 for (auto &LM : LogicalModules) 55 for (auto BLH : LM.BaseLayerHandles) 56 BaseLayer.removeModuleSet(BLH); 57 } 58 59 // If possible, remove this and ~LogicalDylib once the work in the dtor is 60 // moved to members (eg: self-unregistering base layer handles). LogicalDylib(LogicalDylib && RHS)61 LogicalDylib(LogicalDylib &&RHS) 62 : BaseLayer(std::move(RHS.BaseLayer)), 63 LogicalModules(std::move(RHS.LogicalModules)), 64 DylibResources(std::move(RHS.DylibResources)) {} 65 createLogicalModule()66 LogicalModuleHandle createLogicalModule() { 67 LogicalModules.push_back(LogicalModule()); 68 return std::prev(LogicalModules.end()); 69 } 70 addToLogicalModule(LogicalModuleHandle LMH,BaseLayerModuleSetHandleT BaseLayerHandle)71 void addToLogicalModule(LogicalModuleHandle LMH, 72 BaseLayerModuleSetHandleT BaseLayerHandle) { 73 LMH->BaseLayerHandles.push_back(BaseLayerHandle); 74 } 75 getLogicalModuleResources(LogicalModuleHandle LMH)76 LogicalModuleResources& getLogicalModuleResources(LogicalModuleHandle LMH) { 77 return LMH->Resources; 78 } 79 moduleHandlesBegin(LogicalModuleHandle LMH)80 BaseLayerHandleIterator moduleHandlesBegin(LogicalModuleHandle LMH) { 81 return LMH->BaseLayerHandles.begin(); 82 } 83 moduleHandlesEnd(LogicalModuleHandle LMH)84 BaseLayerHandleIterator moduleHandlesEnd(LogicalModuleHandle LMH) { 85 return LMH->BaseLayerHandles.end(); 86 } 87 findSymbolInLogicalModule(LogicalModuleHandle LMH,const std::string & Name,bool ExportedSymbolsOnly)88 JITSymbol findSymbolInLogicalModule(LogicalModuleHandle LMH, 89 const std::string &Name, 90 bool ExportedSymbolsOnly) { 91 92 if (auto StubSym = LMH->Resources.findSymbol(Name, ExportedSymbolsOnly)) 93 return StubSym; 94 95 for (auto BLH : LMH->BaseLayerHandles) 96 if (auto Symbol = BaseLayer.findSymbolIn(BLH, Name, ExportedSymbolsOnly)) 97 return Symbol; 98 return nullptr; 99 } 100 findSymbolInternally(LogicalModuleHandle LMH,const std::string & Name)101 JITSymbol findSymbolInternally(LogicalModuleHandle LMH, 102 const std::string &Name) { 103 if (auto Symbol = findSymbolInLogicalModule(LMH, Name, false)) 104 return Symbol; 105 106 for (auto LMI = LogicalModules.begin(), LME = LogicalModules.end(); 107 LMI != LME; ++LMI) { 108 if (LMI != LMH) 109 if (auto Symbol = findSymbolInLogicalModule(LMI, Name, false)) 110 return Symbol; 111 } 112 113 return nullptr; 114 } 115 findSymbol(const std::string & Name,bool ExportedSymbolsOnly)116 JITSymbol findSymbol(const std::string &Name, bool ExportedSymbolsOnly) { 117 for (auto LMI = LogicalModules.begin(), LME = LogicalModules.end(); 118 LMI != LME; ++LMI) 119 if (auto Sym = findSymbolInLogicalModule(LMI, Name, ExportedSymbolsOnly)) 120 return Sym; 121 return nullptr; 122 } 123 getDylibResources()124 LogicalDylibResources& getDylibResources() { return DylibResources; } 125 126 protected: 127 BaseLayerT BaseLayer; 128 LogicalModuleList LogicalModules; 129 LogicalDylibResources DylibResources; 130 }; 131 132 } // End namespace orc. 133 } // End namespace llvm. 134 135 #endif // LLVM_EXECUTIONENGINE_ORC_LOGICALDYLIB_H 136