Home | History | Annotate | Download | only in Orc
      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.
     37     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 
     51   LogicalDylib(BaseLayerT &BaseLayer) : BaseLayer(BaseLayer) {}
     52 
     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).
     61   LogicalDylib(LogicalDylib &&RHS)
     62       : BaseLayer(std::move(RHS.BaseLayer)),
     63         LogicalModules(std::move(RHS.LogicalModules)),
     64         DylibResources(std::move(RHS.DylibResources)) {}
     65 
     66   LogicalModuleHandle createLogicalModule() {
     67     LogicalModules.push_back(LogicalModule());
     68     return std::prev(LogicalModules.end());
     69   }
     70 
     71   void addToLogicalModule(LogicalModuleHandle LMH,
     72                           BaseLayerModuleSetHandleT BaseLayerHandle) {
     73     LMH->BaseLayerHandles.push_back(BaseLayerHandle);
     74   }
     75 
     76   LogicalModuleResources& getLogicalModuleResources(LogicalModuleHandle LMH) {
     77     return LMH->Resources;
     78   }
     79 
     80   BaseLayerHandleIterator moduleHandlesBegin(LogicalModuleHandle LMH) {
     81     return LMH->BaseLayerHandles.begin();
     82   }
     83 
     84   BaseLayerHandleIterator moduleHandlesEnd(LogicalModuleHandle LMH) {
     85     return LMH->BaseLayerHandles.end();
     86   }
     87 
     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 
    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 
    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 
    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