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     SymbolMap Symbols;
58     for (auto &KV : RTDyld->getSymbolTable())
59       Symbols[ES.getSymbolStringPool().intern(KV.first)] = KV.second;
60     R.resolve(Symbols);
61   }
62 
63   if (NotifyLoaded)
64     NotifyLoaded(K, **ObjFile, *Info);
65 
66   RTDyld->finalizeWithMemoryManagerLocking();
67 
68   {
69     std::lock_guard<std::mutex> Lock(RTDyldLayerMutex);
70     ActiveRTDylds.erase(K);
71   }
72 
73   if (RTDyld->hasError()) {
74     ES.reportError(make_error<StringError>(RTDyld->getErrorString(),
75                                            inconvertibleErrorCode()));
76     R.failMaterialization();
77   }
78 
79   R.finalize();
80 
81   if (NotifyFinalized)
82     NotifyFinalized(K);
83 }
84 
85 void RTDyldObjectLinkingLayer2::mapSectionAddress(
86     VModuleKey K, const void *LocalAddress, JITTargetAddress TargetAddr) const {
87   std::lock_guard<std::mutex> Lock(RTDyldLayerMutex);
88   auto ActiveRTDyldItr = ActiveRTDylds.find(K);
89 
90   assert(ActiveRTDyldItr != ActiveRTDylds.end() &&
91          "No active RTDyld instance found for key");
92   ActiveRTDyldItr->second->mapSectionAddress(LocalAddress, TargetAddr);
93 }
94 
95 } // End namespace orc.
96 } // End namespace llvm.
97