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 llvm {
13 namespace orc {
14 
15 RTDyldObjectLinkingLayer2::RTDyldObjectLinkingLayer2(
16     ExecutionSession &ES, ResourcesGetterFunction GetResources,
17     NotifyLoadedFunction NotifyLoaded, NotifyFinalizedFunction NotifyFinalized)
18     : ObjectLayer(ES), GetResources(std::move(GetResources)),
19       NotifyLoaded(std::move(NotifyLoaded)),
20       NotifyFinalized(std::move(NotifyFinalized)), ProcessAllSections(false) {}
21 
22 void RTDyldObjectLinkingLayer2::emit(MaterializationResponsibility R,
23                                      VModuleKey K,
24                                      std::unique_ptr<MemoryBuffer> O) {
25   assert(O && "Object must not be null");
26 
27   auto &ES = getExecutionSession();
28 
29   auto ObjFile = object::ObjectFile::createObjectFile(*O);
30   if (!ObjFile) {
31     getExecutionSession().reportError(ObjFile.takeError());
32     R.failMaterialization();
33   }
34 
35   auto Resources = GetResources(K);
36 
37   JITSymbolResolverAdapter ResolverAdapter(ES, *Resources.Resolver, &R);
38   auto RTDyld =
39       llvm::make_unique<RuntimeDyld>(*Resources.MemMgr, ResolverAdapter);
40   RTDyld->setProcessAllSections(ProcessAllSections);
41 
42   {
43     std::lock_guard<std::mutex> Lock(RTDyldLayerMutex);
44 
45     assert(!ActiveRTDylds.count(K) &&
46            "An active RTDyld already exists for this key?");
47     ActiveRTDylds[K] = RTDyld.get();
48 
49     assert(!MemMgrs.count(K) &&
50            "A memory manager already exists for this key?");
51     MemMgrs[K] = Resources.MemMgr;
52   }
53 
54   auto Info = RTDyld->loadObject(**ObjFile);
55 
56   {
57     std::set<StringRef> InternalSymbols;
58     for (auto &Sym : (*ObjFile)->symbols()) {
59       if (!(Sym.getFlags() & object::BasicSymbolRef::SF_Global)) {
60         if (auto SymName = Sym.getName())
61           InternalSymbols.insert(*SymName);
62         else {
63           ES.reportError(SymName.takeError());
64           R.failMaterialization();
65           return;
66         }
67       }
68     }
69 
70     SymbolMap Symbols;
71     for (auto &KV : RTDyld->getSymbolTable())
72       if (!InternalSymbols.count(KV.first))
73         Symbols[ES.getSymbolStringPool().intern(KV.first)] = KV.second;
74 
75     R.resolve(Symbols);
76   }
77 
78   if (NotifyLoaded)
79     NotifyLoaded(K, **ObjFile, *Info);
80 
81   RTDyld->finalizeWithMemoryManagerLocking();
82 
83   {
84     std::lock_guard<std::mutex> Lock(RTDyldLayerMutex);
85     ActiveRTDylds.erase(K);
86   }
87 
88   if (RTDyld->hasError()) {
89     ES.reportError(make_error<StringError>(RTDyld->getErrorString(),
90                                            inconvertibleErrorCode()));
91     R.failMaterialization();
92     return;
93   }
94 
95   R.finalize();
96 
97   if (NotifyFinalized)
98     NotifyFinalized(K);
99 }
100 
101 void RTDyldObjectLinkingLayer2::mapSectionAddress(
102     VModuleKey K, const void *LocalAddress, JITTargetAddress TargetAddr) const {
103   std::lock_guard<std::mutex> Lock(RTDyldLayerMutex);
104   auto ActiveRTDyldItr = ActiveRTDylds.find(K);
105 
106   assert(ActiveRTDyldItr != ActiveRTDylds.end() &&
107          "No active RTDyld instance found for key");
108   ActiveRTDyldItr->second->mapSectionAddress(LocalAddress, TargetAddr);
109 }
110 
111 } // End namespace orc.
112 } // End namespace llvm.
113