LCOV - code coverage report
Current view: top level - lib/ExecutionEngine/Orc - RTDyldObjectLinkingLayer.cpp (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 50 63 79.4 %
Date: 2018-10-20 13:21:21 Functions: 6 6 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : //===-- RTDyldObjectLinkingLayer.cpp - RuntimeDyld backed ORC ObjectLayer -===//
       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             : #include "llvm/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.h"
      11             : 
      12             : namespace {
      13             : 
      14             : using namespace llvm;
      15             : using namespace llvm::orc;
      16             : 
      17          31 : class JITDylibSearchOrderResolver : public JITSymbolResolver {
      18             : public:
      19          31 :   JITDylibSearchOrderResolver(MaterializationResponsibility &MR) : MR(MR) {}
      20             : 
      21          14 :   void lookup(const LookupSet &Symbols, OnResolvedFunction OnResolved) {
      22          14 :     auto &ES = MR.getTargetJITDylib().getExecutionSession();
      23             :     SymbolNameSet InternedSymbols;
      24             : 
      25             :     // Intern the requested symbols: lookup takes interned strings.
      26          40 :     for (auto &S : Symbols)
      27          52 :       InternedSymbols.insert(ES.intern(S));
      28             : 
      29             :     // Build an OnResolve callback to unwrap the interned strings and pass them
      30             :     // to the OnResolved callback.
      31             :     // FIXME: Switch to move capture of OnResolved once we have c++14.
      32             :     auto OnResolvedWithUnwrap =
      33          14 :         [OnResolved](Expected<SymbolMap> InternedResult) {
      34             :           if (!InternedResult) {
      35             :             OnResolved(InternedResult.takeError());
      36             :             return;
      37             :           }
      38             : 
      39             :           LookupResult Result;
      40             :           for (auto &KV : *InternedResult)
      41             :             Result[*KV.first] = std::move(KV.second);
      42             :           OnResolved(Result);
      43             :         };
      44             : 
      45             :     // We're not waiting for symbols to be ready. Just log any errors.
      46          14 :     auto OnReady = [&ES](Error Err) { ES.reportError(std::move(Err)); };
      47             : 
      48             :     // Register dependencies for all symbols contained in this set.
      49             :     auto RegisterDependencies = [&](const SymbolDependenceMap &Deps) {
      50          12 :       MR.addDependenciesForAll(Deps);
      51          14 :     };
      52             : 
      53          14 :     MR.getTargetJITDylib().withSearchOrderDo([&](const JITDylibList &JDs) {
      54             :       ES.lookup(JDs, InternedSymbols, OnResolvedWithUnwrap, OnReady,
      55             :                 RegisterDependencies, &MR.getTargetJITDylib());
      56             :     });
      57          14 :   }
      58             : 
      59          31 :   Expected<LookupSet> getResponsibilitySet(const LookupSet &Symbols) {
      60             :     LookupSet Result;
      61             : 
      62         132 :     for (auto &KV : MR.getSymbols()) {
      63         114 :       if (Symbols.count(*KV.first))
      64           6 :         Result.insert(*KV.first);
      65             :     }
      66             : 
      67          31 :     return Result;
      68             :   }
      69             : 
      70             : private:
      71             :   MaterializationResponsibility &MR;
      72             : };
      73             : 
      74             : } // end anonymous namespace
      75             : 
      76             : namespace llvm {
      77             : namespace orc {
      78             : 
      79          17 : RTDyldObjectLinkingLayer::RTDyldObjectLinkingLayer(
      80             :     ExecutionSession &ES, GetMemoryManagerFunction GetMemoryManager,
      81          17 :     NotifyLoadedFunction NotifyLoaded, NotifyEmittedFunction NotifyEmitted)
      82             :     : ObjectLayer(ES), GetMemoryManager(GetMemoryManager),
      83             :       NotifyLoaded(std::move(NotifyLoaded)),
      84          17 :       NotifyEmitted(std::move(NotifyEmitted)) {}
      85             : 
      86          31 : void RTDyldObjectLinkingLayer::emit(MaterializationResponsibility R,
      87             :                                     std::unique_ptr<MemoryBuffer> O) {
      88             :   assert(O && "Object must not be null");
      89             : 
      90             :   // This method launches an asynchronous link step that will fulfill our
      91             :   // materialization responsibility. We need to switch R to be heap
      92             :   // allocated before that happens so it can live as long as the asynchronous
      93             :   // link needs it to (i.e. it must be able to outlive this method).
      94             :   auto SharedR = std::make_shared<MaterializationResponsibility>(std::move(R));
      95             : 
      96          31 :   auto &ES = getExecutionSession();
      97             : 
      98          62 :   auto Obj = object::ObjectFile::createObjectFile(*O);
      99             : 
     100          31 :   if (!Obj) {
     101           0 :     getExecutionSession().reportError(Obj.takeError());
     102           0 :     SharedR->failMaterialization();
     103           0 :     return;
     104             :   }
     105             : 
     106             :   // Collect the internal symbols from the object file: We will need to
     107             :   // filter these later.
     108             :   auto InternalSymbols = std::make_shared<std::set<StringRef>>();
     109             :   {
     110         184 :     for (auto &Sym : (*Obj)->symbols()) {
     111         153 :       if (!(Sym.getFlags() & object::BasicSymbolRef::SF_Global)) {
     112          86 :         if (auto SymName = Sym.getName())
     113             :           InternalSymbols->insert(*SymName);
     114             :         else {
     115           0 :           ES.reportError(SymName.takeError());
     116           0 :           R.failMaterialization();
     117             :           return;
     118             :         }
     119             :       }
     120             :     }
     121             :   }
     122             : 
     123          31 :   auto K = R.getVModuleKey();
     124          62 :   MemMgrs.push_back(GetMemoryManager());
     125             :   auto &MemMgr = *MemMgrs.back();
     126             : 
     127             :   JITDylibSearchOrderResolver Resolver(*SharedR);
     128             : 
     129             :   /* Thoughts on proper cross-dylib weak symbol handling:
     130             :    *
     131             :    * Change selection of canonical defs to be a manually triggered process, and
     132             :    * add a 'canonical' bit to symbol definitions. When canonical def selection
     133             :    * is triggered, sweep the JITDylibs to mark defs as canonical, discard
     134             :    * duplicate defs.
     135             :    */
     136         155 :   jitLinkForORC(
     137          31 :       **Obj, std::move(O), MemMgr, Resolver, ProcessAllSections,
     138           0 :       [this, K, SharedR, &Obj, InternalSymbols](
     139             :           std::unique_ptr<RuntimeDyld::LoadedObjectInfo> LoadedObjInfo,
     140             :           std::map<StringRef, JITEvaluatedSymbol> ResolvedSymbols) {
     141             :         return onObjLoad(K, *SharedR, **Obj, std::move(LoadedObjInfo),
     142             :                          ResolvedSymbols, *InternalSymbols);
     143             :       },
     144           0 :       [this, K, SharedR](Error Err) {
     145             :         onObjEmit(K, *SharedR, std::move(Err));
     146             :       });
     147             : }
     148             : 
     149          31 : Error RTDyldObjectLinkingLayer::onObjLoad(
     150             :     VModuleKey K, MaterializationResponsibility &R, object::ObjectFile &Obj,
     151             :     std::unique_ptr<RuntimeDyld::LoadedObjectInfo> LoadedObjInfo,
     152             :     std::map<StringRef, JITEvaluatedSymbol> Resolved,
     153             :     std::set<StringRef> &InternalSymbols) {
     154             :   SymbolFlagsMap ExtraSymbolsToClaim;
     155             :   SymbolMap Symbols;
     156          71 :   for (auto &KV : Resolved) {
     157             :     // Scan the symbols and add them to the Symbols map for resolution.
     158             : 
     159             :     // We never claim internal symbols.
     160          40 :     if (InternalSymbols.count(KV.first))
     161           0 :       continue;
     162             : 
     163          40 :     auto InternedName = getExecutionSession().intern(KV.first);
     164             :     auto Flags = KV.second.getFlags();
     165             : 
     166             :     // Override object flags and claim responsibility for symbols if
     167             :     // requested.
     168          40 :     if (OverrideObjectFlags || AutoClaimObjectSymbols) {
     169           4 :       auto I = R.getSymbols().find(InternedName);
     170             : 
     171           4 :       if (OverrideObjectFlags && I != R.getSymbols().end())
     172           2 :         Flags = JITSymbolFlags::stripTransientFlags(I->second);
     173           2 :       else if (AutoClaimObjectSymbols && I == R.getSymbols().end())
     174           1 :         ExtraSymbolsToClaim[InternedName] = Flags;
     175             :     }
     176             : 
     177          40 :     Symbols[InternedName] = JITEvaluatedSymbol(KV.second.getAddress(), Flags);
     178             :   }
     179             : 
     180          31 :   if (!ExtraSymbolsToClaim.empty())
     181           2 :     if (auto Err = R.defineMaterializing(ExtraSymbolsToClaim))
     182             :       return Err;
     183             : 
     184          31 :   R.resolve(Symbols);
     185             : 
     186          31 :   if (NotifyLoaded)
     187           0 :     NotifyLoaded(K, Obj, *LoadedObjInfo);
     188             : 
     189             :   return Error::success();
     190             : }
     191             : 
     192          31 : void RTDyldObjectLinkingLayer::onObjEmit(VModuleKey K,
     193             :                                           MaterializationResponsibility &R,
     194             :                                           Error Err) {
     195          31 :   if (Err) {
     196           0 :     getExecutionSession().reportError(std::move(Err));
     197           0 :     R.failMaterialization();
     198           0 :     return;
     199             :   }
     200             : 
     201          31 :   R.emit();
     202             : 
     203          31 :   if (NotifyEmitted)
     204           0 :     NotifyEmitted(K);
     205             : }
     206             : 
     207             : } // End namespace orc.
     208             : } // End namespace llvm.

Generated by: LCOV version 1.13