| Lang Hames | 373f462 | 2018-05-21 23:45:40 +0000 | [diff] [blame] | 1 | //===-- RTDyldObjectLinkingLayer.cpp - RuntimeDyld backed ORC ObjectLayer -===// | 
|  | 2 | // | 
| Chandler Carruth | 2946cd7 | 2019-01-19 08:50:56 +0000 | [diff] [blame] | 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | 
|  | 4 | // See https://llvm.org/LICENSE.txt for license information. | 
|  | 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | 
| Lang Hames | 373f462 | 2018-05-21 23:45:40 +0000 | [diff] [blame] | 6 | // | 
|  | 7 | //===----------------------------------------------------------------------===// | 
|  | 8 |  | 
|  | 9 | #include "llvm/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.h" | 
| Lang Hames | 84217ad | 2020-01-17 14:48:48 -0800 | [diff] [blame] | 10 | #include "llvm/Object/COFF.h" | 
| Lang Hames | 373f462 | 2018-05-21 23:45:40 +0000 | [diff] [blame] | 11 |  | 
| Lang Hames | fd0c1e71 | 2018-07-20 18:31:50 +0000 | [diff] [blame] | 12 | namespace { | 
|  | 13 |  | 
|  | 14 | using namespace llvm; | 
|  | 15 | using namespace llvm::orc; | 
|  | 16 |  | 
| Lang Hames | d5f56c5 | 2018-08-17 21:18:18 +0000 | [diff] [blame] | 17 | class JITDylibSearchOrderResolver : public JITSymbolResolver { | 
| Lang Hames | fd0c1e71 | 2018-07-20 18:31:50 +0000 | [diff] [blame] | 18 | public: | 
| Lang Hames | d5f56c5 | 2018-08-17 21:18:18 +0000 | [diff] [blame] | 19 | JITDylibSearchOrderResolver(MaterializationResponsibility &MR) : MR(MR) {} | 
| Lang Hames | fd0c1e71 | 2018-07-20 18:31:50 +0000 | [diff] [blame] | 20 |  | 
| Lang Hames | adde5ba | 2018-09-25 19:48:46 +0000 | [diff] [blame] | 21 | void lookup(const LookupSet &Symbols, OnResolvedFunction OnResolved) { | 
| Lang Hames | d5f56c5 | 2018-08-17 21:18:18 +0000 | [diff] [blame] | 22 | auto &ES = MR.getTargetJITDylib().getExecutionSession(); | 
| Lang Hames | 674df13 | 2019-11-25 21:57:27 -0800 | [diff] [blame] | 23 | SymbolLookupSet InternedSymbols; | 
| Lang Hames | fd0c1e71 | 2018-07-20 18:31:50 +0000 | [diff] [blame] | 24 |  | 
| Lang Hames | adde5ba | 2018-09-25 19:48:46 +0000 | [diff] [blame] | 25 | // Intern the requested symbols: lookup takes interned strings. | 
| Lang Hames | fd0c1e71 | 2018-07-20 18:31:50 +0000 | [diff] [blame] | 26 | for (auto &S : Symbols) | 
| Lang Hames | 674df13 | 2019-11-25 21:57:27 -0800 | [diff] [blame] | 27 | InternedSymbols.add(ES.intern(S)); | 
| Lang Hames | fd0c1e71 | 2018-07-20 18:31:50 +0000 | [diff] [blame] | 28 |  | 
| Lang Hames | adde5ba | 2018-09-25 19:48:46 +0000 | [diff] [blame] | 29 | // Build an OnResolve callback to unwrap the interned strings and pass them | 
|  | 30 | // to the OnResolved callback. | 
| Lang Hames | adde5ba | 2018-09-25 19:48:46 +0000 | [diff] [blame] | 31 | auto OnResolvedWithUnwrap = | 
| Benjamin Kramer | ce74c3b | 2019-09-13 11:35:33 +0000 | [diff] [blame] | 32 | [OnResolved = std::move(OnResolved)]( | 
|  | 33 | Expected<SymbolMap> InternedResult) mutable { | 
| Lang Hames | adde5ba | 2018-09-25 19:48:46 +0000 | [diff] [blame] | 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 |  | 
| Lang Hames | adde5ba | 2018-09-25 19:48:46 +0000 | [diff] [blame] | 45 | // Register dependencies for all symbols contained in this set. | 
| Lang Hames | a48d108 | 2018-07-20 22:22:19 +0000 | [diff] [blame] | 46 | auto RegisterDependencies = [&](const SymbolDependenceMap &Deps) { | 
| Lang Hames | 960246d | 2018-07-21 00:12:05 +0000 | [diff] [blame] | 47 | MR.addDependenciesForAll(Deps); | 
| Lang Hames | fd0c1e71 | 2018-07-20 18:31:50 +0000 | [diff] [blame] | 48 | }; | 
|  | 49 |  | 
| Lang Hames | 674df13 | 2019-11-25 21:57:27 -0800 | [diff] [blame] | 50 | JITDylibSearchOrder SearchOrder; | 
| Lang Hames | 23cb2e7 | 2018-10-23 23:01:39 +0000 | [diff] [blame] | 51 | MR.getTargetJITDylib().withSearchOrderDo( | 
| Lang Hames | 674df13 | 2019-11-25 21:57:27 -0800 | [diff] [blame] | 52 | [&](const JITDylibSearchOrder &JDs) { SearchOrder = JDs; }); | 
|  | 53 | ES.lookup(LookupKind::Static, SearchOrder, InternedSymbols, | 
|  | 54 | SymbolState::Resolved, std::move(OnResolvedWithUnwrap), | 
|  | 55 | RegisterDependencies); | 
| Lang Hames | fd0c1e71 | 2018-07-20 18:31:50 +0000 | [diff] [blame] | 56 | } | 
|  | 57 |  | 
| Lang Hames | 6cadc7c | 2018-08-28 21:18:05 +0000 | [diff] [blame] | 58 | Expected<LookupSet> getResponsibilitySet(const LookupSet &Symbols) { | 
|  | 59 | LookupSet Result; | 
| Lang Hames | a48d108 | 2018-07-20 22:22:19 +0000 | [diff] [blame] | 60 |  | 
| Lang Hames | 6cadc7c | 2018-08-28 21:18:05 +0000 | [diff] [blame] | 61 | for (auto &KV : MR.getSymbols()) { | 
|  | 62 | if (Symbols.count(*KV.first)) | 
|  | 63 | Result.insert(*KV.first); | 
|  | 64 | } | 
| Lang Hames | fd0c1e71 | 2018-07-20 18:31:50 +0000 | [diff] [blame] | 65 |  | 
|  | 66 | return Result; | 
|  | 67 | } | 
|  | 68 |  | 
|  | 69 | private: | 
| Lang Hames | fd0c1e71 | 2018-07-20 18:31:50 +0000 | [diff] [blame] | 70 | MaterializationResponsibility &MR; | 
|  | 71 | }; | 
|  | 72 |  | 
|  | 73 | } // end anonymous namespace | 
|  | 74 |  | 
| Lang Hames | 373f462 | 2018-05-21 23:45:40 +0000 | [diff] [blame] | 75 | namespace llvm { | 
|  | 76 | namespace orc { | 
|  | 77 |  | 
| Lang Hames | 079df9a | 2018-10-15 22:56:10 +0000 | [diff] [blame] | 78 | RTDyldObjectLinkingLayer::RTDyldObjectLinkingLayer( | 
| Lang Hames | 42a3b4f | 2019-05-01 22:40:23 +0000 | [diff] [blame] | 79 | ExecutionSession &ES, GetMemoryManagerFunction GetMemoryManager) | 
|  | 80 | : ObjectLayer(ES), GetMemoryManager(GetMemoryManager) {} | 
| Lang Hames | 373f462 | 2018-05-21 23:45:40 +0000 | [diff] [blame] | 81 |  | 
| Lang Hames | 9f4f237 | 2019-12-20 21:08:35 -0800 | [diff] [blame] | 82 | RTDyldObjectLinkingLayer::~RTDyldObjectLinkingLayer() { | 
|  | 83 | std::lock_guard<std::mutex> Lock(RTDyldLayerMutex); | 
|  | 84 | for (auto &MemMgr : MemMgrs) | 
|  | 85 | MemMgr->deregisterEHFrames(); | 
|  | 86 | } | 
|  | 87 |  | 
| Lang Hames | 079df9a | 2018-10-15 22:56:10 +0000 | [diff] [blame] | 88 | void RTDyldObjectLinkingLayer::emit(MaterializationResponsibility R, | 
| Lang Hames | 8b94274 | 2018-10-16 20:13:06 +0000 | [diff] [blame] | 89 | std::unique_ptr<MemoryBuffer> O) { | 
| Lang Hames | 4caa2f7 | 2018-05-23 21:27:01 +0000 | [diff] [blame] | 90 | assert(O && "Object must not be null"); | 
| Lang Hames | 85fb997 | 2019-12-16 02:50:40 -0800 | [diff] [blame] | 91 | dbgs() << "Emitting via RTDyldObjectLinkingLayer:\n" | 
|  | 92 | << R.getSymbols() << "\n"; | 
| Lang Hames | abeedf1 | 2018-09-25 22:57:44 +0000 | [diff] [blame] | 93 | // This method launches an asynchronous link step that will fulfill our | 
|  | 94 | // materialization responsibility. We need to switch R to be heap | 
|  | 95 | // allocated before that happens so it can live as long as the asynchronous | 
|  | 96 | // link needs it to (i.e. it must be able to outlive this method). | 
|  | 97 | auto SharedR = std::make_shared<MaterializationResponsibility>(std::move(R)); | 
|  | 98 |  | 
| Lang Hames | 373f462 | 2018-05-21 23:45:40 +0000 | [diff] [blame] | 99 | auto &ES = getExecutionSession(); | 
|  | 100 |  | 
| Lang Hames | 42a3b4f | 2019-05-01 22:40:23 +0000 | [diff] [blame] | 101 | // Create a MemoryBufferRef backed MemoryBuffer (i.e. shallow) copy of the | 
|  | 102 | // the underlying buffer to pass into RuntimeDyld. This allows us to hold | 
|  | 103 | // ownership of the real underlying buffer and return it to the user once | 
|  | 104 | // the object has been emitted. | 
|  | 105 | auto ObjBuffer = MemoryBuffer::getMemBuffer(O->getMemBufferRef(), false); | 
|  | 106 |  | 
|  | 107 | auto Obj = object::ObjectFile::createObjectFile(*ObjBuffer); | 
| Lang Hames | abeedf1 | 2018-09-25 22:57:44 +0000 | [diff] [blame] | 108 |  | 
|  | 109 | if (!Obj) { | 
|  | 110 | getExecutionSession().reportError(Obj.takeError()); | 
|  | 111 | SharedR->failMaterialization(); | 
|  | 112 | return; | 
|  | 113 | } | 
|  | 114 |  | 
|  | 115 | // Collect the internal symbols from the object file: We will need to | 
|  | 116 | // filter these later. | 
|  | 117 | auto InternalSymbols = std::make_shared<std::set<StringRef>>(); | 
|  | 118 | { | 
|  | 119 | for (auto &Sym : (*Obj)->symbols()) { | 
|  | 120 | if (!(Sym.getFlags() & object::BasicSymbolRef::SF_Global)) { | 
|  | 121 | if (auto SymName = Sym.getName()) | 
|  | 122 | InternalSymbols->insert(*SymName); | 
|  | 123 | else { | 
|  | 124 | ES.reportError(SymName.takeError()); | 
|  | 125 | R.failMaterialization(); | 
|  | 126 | return; | 
|  | 127 | } | 
|  | 128 | } | 
|  | 129 | } | 
| Lang Hames | 373f462 | 2018-05-21 23:45:40 +0000 | [diff] [blame] | 130 | } | 
|  | 131 |  | 
| Lang Hames | 8b94274 | 2018-10-16 20:13:06 +0000 | [diff] [blame] | 132 | auto K = R.getVModuleKey(); | 
| Lang Hames | 95abade | 2018-10-22 21:17:56 +0000 | [diff] [blame] | 133 | RuntimeDyld::MemoryManager *MemMgr = nullptr; | 
|  | 134 |  | 
|  | 135 | // Create a record a memory manager for this object. | 
|  | 136 | { | 
|  | 137 | auto Tmp = GetMemoryManager(); | 
|  | 138 | std::lock_guard<std::mutex> Lock(RTDyldLayerMutex); | 
|  | 139 | MemMgrs.push_back(std::move(Tmp)); | 
|  | 140 | MemMgr = MemMgrs.back().get(); | 
|  | 141 | } | 
| Lang Hames | 373f462 | 2018-05-21 23:45:40 +0000 | [diff] [blame] | 142 |  | 
| Lang Hames | abeedf1 | 2018-09-25 22:57:44 +0000 | [diff] [blame] | 143 | JITDylibSearchOrderResolver Resolver(*SharedR); | 
| Lang Hames | 373f462 | 2018-05-21 23:45:40 +0000 | [diff] [blame] | 144 |  | 
| Lang Hames | abeedf1 | 2018-09-25 22:57:44 +0000 | [diff] [blame] | 145 | jitLinkForORC( | 
| Lang Hames | 95abade | 2018-10-22 21:17:56 +0000 | [diff] [blame] | 146 | **Obj, std::move(O), *MemMgr, Resolver, ProcessAllSections, | 
| Lang Hames | abeedf1 | 2018-09-25 22:57:44 +0000 | [diff] [blame] | 147 | [this, K, SharedR, &Obj, InternalSymbols]( | 
|  | 148 | std::unique_ptr<RuntimeDyld::LoadedObjectInfo> LoadedObjInfo, | 
|  | 149 | std::map<StringRef, JITEvaluatedSymbol> ResolvedSymbols) { | 
|  | 150 | return onObjLoad(K, *SharedR, **Obj, std::move(LoadedObjInfo), | 
|  | 151 | ResolvedSymbols, *InternalSymbols); | 
|  | 152 | }, | 
| Benjamin Kramer | ce74c3b | 2019-09-13 11:35:33 +0000 | [diff] [blame] | 153 | [this, K, SharedR, O = std::move(O)](Error Err) mutable { | 
|  | 154 | onObjEmit(K, std::move(O), *SharedR, std::move(Err)); | 
| Lang Hames | abeedf1 | 2018-09-25 22:57:44 +0000 | [diff] [blame] | 155 | }); | 
|  | 156 | } | 
|  | 157 |  | 
| Lang Hames | 079df9a | 2018-10-15 22:56:10 +0000 | [diff] [blame] | 158 | Error RTDyldObjectLinkingLayer::onObjLoad( | 
| Lang Hames | abeedf1 | 2018-09-25 22:57:44 +0000 | [diff] [blame] | 159 | VModuleKey K, MaterializationResponsibility &R, object::ObjectFile &Obj, | 
|  | 160 | std::unique_ptr<RuntimeDyld::LoadedObjectInfo> LoadedObjInfo, | 
|  | 161 | std::map<StringRef, JITEvaluatedSymbol> Resolved, | 
|  | 162 | std::set<StringRef> &InternalSymbols) { | 
|  | 163 | SymbolFlagsMap ExtraSymbolsToClaim; | 
|  | 164 | SymbolMap Symbols; | 
| Lang Hames | 84217ad | 2020-01-17 14:48:48 -0800 | [diff] [blame] | 165 |  | 
|  | 166 | // Hack to support COFF constant pool comdats introduced during compilation: | 
|  | 167 | // (See http://llvm.org/PR40074) | 
|  | 168 | if (auto *COFFObj = dyn_cast<object::COFFObjectFile>(&Obj)) { | 
|  | 169 | auto &ES = getExecutionSession(); | 
|  | 170 |  | 
|  | 171 | // For all resolved symbols that are not already in the responsibilty set: | 
|  | 172 | // check whether the symbol is in a comdat section and if so mark it as | 
|  | 173 | // weak. | 
|  | 174 | for (auto &Sym : COFFObj->symbols()) { | 
|  | 175 | if (Sym.getFlags() & object::BasicSymbolRef::SF_Undefined) | 
|  | 176 | continue; | 
|  | 177 | auto Name = Sym.getName(); | 
|  | 178 | if (!Name) | 
|  | 179 | return Name.takeError(); | 
|  | 180 | auto I = Resolved.find(*Name); | 
|  | 181 |  | 
|  | 182 | // Skip unresolved symbols, internal symbols, and symbols that are | 
|  | 183 | // already in the responsibility set. | 
|  | 184 | if (I == Resolved.end() || InternalSymbols.count(*Name) || | 
|  | 185 | R.getSymbols().count(ES.intern(*Name))) | 
|  | 186 | continue; | 
|  | 187 | auto Sec = Sym.getSection(); | 
|  | 188 | if (!Sec) | 
|  | 189 | return Sec.takeError(); | 
|  | 190 | if (*Sec == COFFObj->section_end()) | 
|  | 191 | continue; | 
|  | 192 | auto &COFFSec = *COFFObj->getCOFFSection(**Sec); | 
|  | 193 | if (COFFSec.Characteristics & COFF::IMAGE_SCN_LNK_COMDAT) | 
|  | 194 | I->second.setFlags(I->second.getFlags() | JITSymbolFlags::Weak); | 
|  | 195 | } | 
|  | 196 | } | 
|  | 197 |  | 
| Lang Hames | abeedf1 | 2018-09-25 22:57:44 +0000 | [diff] [blame] | 198 | for (auto &KV : Resolved) { | 
|  | 199 | // Scan the symbols and add them to the Symbols map for resolution. | 
|  | 200 |  | 
|  | 201 | // We never claim internal symbols. | 
|  | 202 | if (InternalSymbols.count(KV.first)) | 
|  | 203 | continue; | 
|  | 204 |  | 
| Lang Hames | 71d781c | 2018-09-30 23:18:24 +0000 | [diff] [blame] | 205 | auto InternedName = getExecutionSession().intern(KV.first); | 
| Lang Hames | abeedf1 | 2018-09-25 22:57:44 +0000 | [diff] [blame] | 206 | auto Flags = KV.second.getFlags(); | 
|  | 207 |  | 
|  | 208 | // Override object flags and claim responsibility for symbols if | 
|  | 209 | // requested. | 
|  | 210 | if (OverrideObjectFlags || AutoClaimObjectSymbols) { | 
|  | 211 | auto I = R.getSymbols().find(InternedName); | 
|  | 212 |  | 
|  | 213 | if (OverrideObjectFlags && I != R.getSymbols().end()) | 
| Lang Hames | eb5ee30 | 2019-05-28 23:35:44 +0000 | [diff] [blame] | 214 | Flags = I->second; | 
| Lang Hames | abeedf1 | 2018-09-25 22:57:44 +0000 | [diff] [blame] | 215 | else if (AutoClaimObjectSymbols && I == R.getSymbols().end()) | 
|  | 216 | ExtraSymbolsToClaim[InternedName] = Flags; | 
| Lang Hames | 68c9b8d | 2018-06-18 18:01:43 +0000 | [diff] [blame] | 217 | } | 
|  | 218 |  | 
| Lang Hames | abeedf1 | 2018-09-25 22:57:44 +0000 | [diff] [blame] | 219 | Symbols[InternedName] = JITEvaluatedSymbol(KV.second.getAddress(), Flags); | 
| Lang Hames | 373f462 | 2018-05-21 23:45:40 +0000 | [diff] [blame] | 220 | } | 
|  | 221 |  | 
| Lang Hames | 84217ad | 2020-01-17 14:48:48 -0800 | [diff] [blame] | 222 | if (!ExtraSymbolsToClaim.empty()) { | 
| Lang Hames | abeedf1 | 2018-09-25 22:57:44 +0000 | [diff] [blame] | 223 | if (auto Err = R.defineMaterializing(ExtraSymbolsToClaim)) | 
|  | 224 | return Err; | 
|  | 225 |  | 
| Lang Hames | 84217ad | 2020-01-17 14:48:48 -0800 | [diff] [blame] | 226 | // If we claimed responsibility for any weak symbols but were rejected then | 
|  | 227 | // we need to remove them from the resolved set. | 
|  | 228 | for (auto &KV : ExtraSymbolsToClaim) | 
|  | 229 | if (KV.second.isWeak() && !R.getSymbols().count(KV.first)) | 
|  | 230 | Symbols.erase(KV.first); | 
|  | 231 | } | 
|  | 232 |  | 
| Lang Hames | 85fb997 | 2019-12-16 02:50:40 -0800 | [diff] [blame] | 233 | if (const auto &InitSym = R.getInitializerSymbol()) | 
|  | 234 | Symbols[InitSym] = JITEvaluatedSymbol(); | 
|  | 235 |  | 
| Lang Hames | e00585c | 2019-08-23 20:37:31 +0000 | [diff] [blame] | 236 | if (auto Err = R.notifyResolved(Symbols)) { | 
|  | 237 | R.failMaterialization(); | 
|  | 238 | return Err; | 
|  | 239 | } | 
| Lang Hames | abeedf1 | 2018-09-25 22:57:44 +0000 | [diff] [blame] | 240 |  | 
| Lang Hames | 373f462 | 2018-05-21 23:45:40 +0000 | [diff] [blame] | 241 | if (NotifyLoaded) | 
| Lang Hames | abeedf1 | 2018-09-25 22:57:44 +0000 | [diff] [blame] | 242 | NotifyLoaded(K, Obj, *LoadedObjInfo); | 
| Lang Hames | 373f462 | 2018-05-21 23:45:40 +0000 | [diff] [blame] | 243 |  | 
| Lang Hames | abeedf1 | 2018-09-25 22:57:44 +0000 | [diff] [blame] | 244 | return Error::success(); | 
|  | 245 | } | 
| Lang Hames | 373f462 | 2018-05-21 23:45:40 +0000 | [diff] [blame] | 246 |  | 
| Lang Hames | 42a3b4f | 2019-05-01 22:40:23 +0000 | [diff] [blame] | 247 | void RTDyldObjectLinkingLayer::onObjEmit( | 
|  | 248 | VModuleKey K, std::unique_ptr<MemoryBuffer> ObjBuffer, | 
|  | 249 | MaterializationResponsibility &R, Error Err) { | 
| Lang Hames | abeedf1 | 2018-09-25 22:57:44 +0000 | [diff] [blame] | 250 | if (Err) { | 
|  | 251 | getExecutionSession().reportError(std::move(Err)); | 
| Lang Hames | 373f462 | 2018-05-21 23:45:40 +0000 | [diff] [blame] | 252 | R.failMaterialization(); | 
| Lang Hames | 68c9b8d | 2018-06-18 18:01:43 +0000 | [diff] [blame] | 253 | return; | 
| Lang Hames | 373f462 | 2018-05-21 23:45:40 +0000 | [diff] [blame] | 254 | } | 
|  | 255 |  | 
| Lang Hames | e00585c | 2019-08-23 20:37:31 +0000 | [diff] [blame] | 256 | if (auto Err = R.notifyEmitted()) { | 
|  | 257 | getExecutionSession().reportError(std::move(Err)); | 
|  | 258 | R.failMaterialization(); | 
|  | 259 | return; | 
|  | 260 | } | 
| Lang Hames | 373f462 | 2018-05-21 23:45:40 +0000 | [diff] [blame] | 261 |  | 
| Lang Hames | 76e21c9 | 2018-08-18 02:06:18 +0000 | [diff] [blame] | 262 | if (NotifyEmitted) | 
| Lang Hames | 42a3b4f | 2019-05-01 22:40:23 +0000 | [diff] [blame] | 263 | NotifyEmitted(K, std::move(ObjBuffer)); | 
| Lang Hames | 373f462 | 2018-05-21 23:45:40 +0000 | [diff] [blame] | 264 | } | 
|  | 265 |  | 
| Lang Hames | 1716454 | 2019-07-17 16:40:52 +0000 | [diff] [blame] | 266 | LegacyRTDyldObjectLinkingLayer::LegacyRTDyldObjectLinkingLayer( | 
|  | 267 | ExecutionSession &ES, ResourcesGetter GetResources, | 
|  | 268 | NotifyLoadedFtor NotifyLoaded, NotifyFinalizedFtor NotifyFinalized, | 
|  | 269 | NotifyFreedFtor NotifyFreed) | 
|  | 270 | : ES(ES), GetResources(std::move(GetResources)), | 
|  | 271 | NotifyLoaded(std::move(NotifyLoaded)), | 
|  | 272 | NotifyFinalized(std::move(NotifyFinalized)), | 
|  | 273 | NotifyFreed(std::move(NotifyFreed)), ProcessAllSections(false) {} | 
|  | 274 |  | 
| Lang Hames | 373f462 | 2018-05-21 23:45:40 +0000 | [diff] [blame] | 275 | } // End namespace orc. | 
|  | 276 | } // End namespace llvm. |