1 //===---- ExecutionUtils.cpp - Utilities for executing functions in Orc ---===// 2 // 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 6 // 7 //===----------------------------------------------------------------------===// 8 9 #include "llvm/ExecutionEngine/Orc/ExecutionUtils.h" 10 #include "llvm/ExecutionEngine/JITLink/x86_64.h" 11 #include "llvm/ExecutionEngine/Orc/AbsoluteSymbols.h" 12 #include "llvm/ExecutionEngine/Orc/Layer.h" 13 #include "llvm/ExecutionEngine/Orc/LoadLinkableFile.h" 14 #include "llvm/ExecutionEngine/Orc/MachO.h" 15 #include "llvm/ExecutionEngine/Orc/ObjectFileInterface.h" 16 #include "llvm/ExecutionEngine/Orc/SymbolStringPool.h" 17 #include "llvm/IR/Constants.h" 18 #include "llvm/IR/Function.h" 19 #include "llvm/IR/GlobalVariable.h" 20 #include "llvm/IR/Module.h" 21 #include "llvm/MC/TargetRegistry.h" 22 #include "llvm/Object/MachOUniversal.h" 23 #include "llvm/Target/TargetMachine.h" 24 #include <string> 25 26 namespace llvm { 27 namespace orc { 28 29 CtorDtorIterator::CtorDtorIterator(const GlobalVariable *GV, bool End) 30 : InitList( 31 GV ? dyn_cast_or_null<ConstantArray>(GV->getInitializer()) : nullptr), 32 I((InitList && End) ? InitList->getNumOperands() : 0) { 33 } 34 35 bool CtorDtorIterator::operator==(const CtorDtorIterator &Other) const { 36 assert(InitList == Other.InitList && "Incomparable iterators."); 37 return I == Other.I; 38 } 39 40 bool CtorDtorIterator::operator!=(const CtorDtorIterator &Other) const { 41 return !(*this == Other); 42 } 43 44 CtorDtorIterator& CtorDtorIterator::operator++() { 45 ++I; 46 return *this; 47 } 48 49 CtorDtorIterator CtorDtorIterator::operator++(int) { 50 CtorDtorIterator Temp = *this; 51 ++I; 52 return Temp; 53 } 54 55 CtorDtorIterator::Element CtorDtorIterator::operator*() const { 56 ConstantStruct *CS = dyn_cast<ConstantStruct>(InitList->getOperand(I)); 57 assert(CS && "Unrecognized type in llvm.global_ctors/llvm.global_dtors"); 58 59 Constant *FuncC = CS->getOperand(1); 60 Function *Func = nullptr; 61 62 // Extract function pointer, pulling off any casts. 63 while (FuncC) { 64 if (Function *F = dyn_cast_or_null<Function>(FuncC)) { 65 Func = F; 66 break; 67 } else if (ConstantExpr *CE = dyn_cast_or_null<ConstantExpr>(FuncC)) { 68 if (CE->isCast()) 69 FuncC = CE->getOperand(0); 70 else 71 break; 72 } else { 73 // This isn't anything we recognize. Bail out with Func left set to null. 74 break; 75 } 76 } 77 78 auto *Priority = cast<ConstantInt>(CS->getOperand(0)); 79 Value *Data = CS->getNumOperands() == 3 ? CS->getOperand(2) : nullptr; 80 if (Data && !isa<GlobalValue>(Data)) 81 Data = nullptr; 82 return Element(Priority->getZExtValue(), Func, Data); 83 } 84 85 iterator_range<CtorDtorIterator> getConstructors(const Module &M) { 86 const GlobalVariable *CtorsList = M.getNamedGlobal("llvm.global_ctors"); 87 return make_range(CtorDtorIterator(CtorsList, false), 88 CtorDtorIterator(CtorsList, true)); 89 } 90 91 iterator_range<CtorDtorIterator> getDestructors(const Module &M) { 92 const GlobalVariable *DtorsList = M.getNamedGlobal("llvm.global_dtors"); 93 return make_range(CtorDtorIterator(DtorsList, false), 94 CtorDtorIterator(DtorsList, true)); 95 } 96 97 bool StaticInitGVIterator::isStaticInitGlobal(GlobalValue &GV) { 98 if (GV.isDeclaration()) 99 return false; 100 101 if (GV.hasName() && (GV.getName() == "llvm.global_ctors" || 102 GV.getName() == "llvm.global_dtors")) 103 return true; 104 105 if (ObjFmt == Triple::MachO) { 106 // FIXME: These section checks are too strict: We should match first and 107 // second word split by comma. 108 if (GV.hasSection() && 109 (GV.getSection().starts_with("__DATA,__objc_classlist") || 110 GV.getSection().starts_with("__DATA,__objc_selrefs"))) 111 return true; 112 } 113 114 return false; 115 } 116 117 void CtorDtorRunner::add(iterator_range<CtorDtorIterator> CtorDtors) { 118 if (CtorDtors.empty()) 119 return; 120 121 MangleAndInterner Mangle( 122 JD.getExecutionSession(), 123 (*CtorDtors.begin()).Func->getDataLayout()); 124 125 for (auto CtorDtor : CtorDtors) { 126 assert(CtorDtor.Func && CtorDtor.Func->hasName() && 127 "Ctor/Dtor function must be named to be runnable under the JIT"); 128 129 // FIXME: Maybe use a symbol promoter here instead. 130 if (CtorDtor.Func->hasLocalLinkage()) { 131 CtorDtor.Func->setLinkage(GlobalValue::ExternalLinkage); 132 CtorDtor.Func->setVisibility(GlobalValue::HiddenVisibility); 133 } 134 135 if (CtorDtor.Data && cast<GlobalValue>(CtorDtor.Data)->isDeclaration()) 136 continue; 137 138 CtorDtorsByPriority[CtorDtor.Priority].push_back( 139 Mangle(CtorDtor.Func->getName())); 140 } 141 } 142 143 Error CtorDtorRunner::run() { 144 using CtorDtorTy = void (*)(); 145 146 SymbolLookupSet LookupSet; 147 for (auto &KV : CtorDtorsByPriority) 148 for (auto &Name : KV.second) 149 LookupSet.add(Name); 150 assert(!LookupSet.containsDuplicates() && 151 "Ctor/Dtor list contains duplicates"); 152 153 auto &ES = JD.getExecutionSession(); 154 if (auto CtorDtorMap = ES.lookup( 155 makeJITDylibSearchOrder(&JD, JITDylibLookupFlags::MatchAllSymbols), 156 std::move(LookupSet))) { 157 for (auto &KV : CtorDtorsByPriority) { 158 for (auto &Name : KV.second) { 159 assert(CtorDtorMap->count(Name) && "No entry for Name"); 160 auto CtorDtor = (*CtorDtorMap)[Name].getAddress().toPtr<CtorDtorTy>(); 161 CtorDtor(); 162 } 163 } 164 CtorDtorsByPriority.clear(); 165 return Error::success(); 166 } else 167 return CtorDtorMap.takeError(); 168 } 169 170 void LocalCXXRuntimeOverridesBase::runDestructors() { 171 auto& CXXDestructorDataPairs = DSOHandleOverride; 172 for (auto &P : CXXDestructorDataPairs) 173 P.first(P.second); 174 CXXDestructorDataPairs.clear(); 175 } 176 177 int LocalCXXRuntimeOverridesBase::CXAAtExitOverride(DestructorPtr Destructor, 178 void *Arg, 179 void *DSOHandle) { 180 auto& CXXDestructorDataPairs = 181 *reinterpret_cast<CXXDestructorDataPairList*>(DSOHandle); 182 CXXDestructorDataPairs.push_back(std::make_pair(Destructor, Arg)); 183 return 0; 184 } 185 186 Error LocalCXXRuntimeOverrides::enable(JITDylib &JD, 187 MangleAndInterner &Mangle) { 188 SymbolMap RuntimeInterposes; 189 RuntimeInterposes[Mangle("__dso_handle")] = { 190 ExecutorAddr::fromPtr(&DSOHandleOverride), JITSymbolFlags::Exported}; 191 RuntimeInterposes[Mangle("__cxa_atexit")] = { 192 ExecutorAddr::fromPtr(&CXAAtExitOverride), JITSymbolFlags::Exported}; 193 194 return JD.define(absoluteSymbols(std::move(RuntimeInterposes))); 195 } 196 197 void ItaniumCXAAtExitSupport::registerAtExit(void (*F)(void *), void *Ctx, 198 void *DSOHandle) { 199 std::lock_guard<std::mutex> Lock(AtExitsMutex); 200 AtExitRecords[DSOHandle].push_back({F, Ctx}); 201 } 202 203 void ItaniumCXAAtExitSupport::runAtExits(void *DSOHandle) { 204 std::vector<AtExitRecord> AtExitsToRun; 205 206 { 207 std::lock_guard<std::mutex> Lock(AtExitsMutex); 208 auto I = AtExitRecords.find(DSOHandle); 209 if (I != AtExitRecords.end()) { 210 AtExitsToRun = std::move(I->second); 211 AtExitRecords.erase(I); 212 } 213 } 214 215 while (!AtExitsToRun.empty()) { 216 AtExitsToRun.back().F(AtExitsToRun.back().Ctx); 217 AtExitsToRun.pop_back(); 218 } 219 } 220 221 DynamicLibrarySearchGenerator::DynamicLibrarySearchGenerator( 222 sys::DynamicLibrary Dylib, char GlobalPrefix, SymbolPredicate Allow, 223 AddAbsoluteSymbolsFn AddAbsoluteSymbols) 224 : Dylib(std::move(Dylib)), Allow(std::move(Allow)), 225 AddAbsoluteSymbols(std::move(AddAbsoluteSymbols)), 226 GlobalPrefix(GlobalPrefix) {} 227 228 Expected<std::unique_ptr<DynamicLibrarySearchGenerator>> 229 DynamicLibrarySearchGenerator::Load(const char *FileName, char GlobalPrefix, 230 SymbolPredicate Allow, 231 AddAbsoluteSymbolsFn AddAbsoluteSymbols) { 232 std::string ErrMsg; 233 auto Lib = sys::DynamicLibrary::getPermanentLibrary(FileName, &ErrMsg); 234 if (!Lib.isValid()) 235 return make_error<StringError>(std::move(ErrMsg), inconvertibleErrorCode()); 236 return std::make_unique<DynamicLibrarySearchGenerator>( 237 std::move(Lib), GlobalPrefix, std::move(Allow), 238 std::move(AddAbsoluteSymbols)); 239 } 240 241 Error DynamicLibrarySearchGenerator::tryToGenerate( 242 LookupState &LS, LookupKind K, JITDylib &JD, 243 JITDylibLookupFlags JDLookupFlags, const SymbolLookupSet &Symbols) { 244 orc::SymbolMap NewSymbols; 245 246 bool HasGlobalPrefix = (GlobalPrefix != '\0'); 247 248 for (auto &KV : Symbols) { 249 auto &Name = KV.first; 250 251 if ((*Name).empty()) 252 continue; 253 254 if (Allow && !Allow(Name)) 255 continue; 256 257 if (HasGlobalPrefix && (*Name).front() != GlobalPrefix) 258 continue; 259 260 std::string Tmp((*Name).data() + HasGlobalPrefix, 261 (*Name).size() - HasGlobalPrefix); 262 if (void *P = Dylib.getAddressOfSymbol(Tmp.c_str())) 263 NewSymbols[Name] = {ExecutorAddr::fromPtr(P), JITSymbolFlags::Exported}; 264 } 265 266 if (NewSymbols.empty()) 267 return Error::success(); 268 269 if (AddAbsoluteSymbols) 270 return AddAbsoluteSymbols(JD, std::move(NewSymbols)); 271 return JD.define(absoluteSymbols(std::move(NewSymbols))); 272 } 273 274 StaticLibraryDefinitionGenerator::VisitMembersFunction 275 StaticLibraryDefinitionGenerator::loadAllObjectFileMembers(ObjectLayer &L, 276 JITDylib &JD) { 277 return [&](object::Archive &A, MemoryBufferRef Buf, 278 size_t Index) -> Expected<bool> { 279 switch (identify_magic(Buf.getBuffer())) { 280 case file_magic::elf_relocatable: 281 case file_magic::macho_object: 282 case file_magic::coff_object: 283 if (auto Err = L.add(JD, createMemberBuffer(A, Buf, Index))) 284 return std::move(Err); 285 // Since we've loaded it already, mark this as not loadable. 286 return false; 287 default: 288 // Non-object-file members are not loadable. 289 return false; 290 } 291 }; 292 } 293 294 Expected<std::unique_ptr<StaticLibraryDefinitionGenerator>> 295 StaticLibraryDefinitionGenerator::Load( 296 ObjectLayer &L, const char *FileName, VisitMembersFunction VisitMembers, 297 GetObjectFileInterface GetObjFileInterface) { 298 299 const auto &TT = L.getExecutionSession().getTargetTriple(); 300 auto Linkable = loadLinkableFile(FileName, TT, LoadArchives::Required); 301 if (!Linkable) 302 return Linkable.takeError(); 303 304 return Create(L, std::move(Linkable->first), std::move(VisitMembers), 305 std::move(GetObjFileInterface)); 306 } 307 308 Expected<std::unique_ptr<StaticLibraryDefinitionGenerator>> 309 StaticLibraryDefinitionGenerator::Create( 310 ObjectLayer &L, std::unique_ptr<MemoryBuffer> ArchiveBuffer, 311 std::unique_ptr<object::Archive> Archive, VisitMembersFunction VisitMembers, 312 GetObjectFileInterface GetObjFileInterface) { 313 314 DenseSet<uint64_t> Excluded; 315 316 if (VisitMembers) { 317 size_t Index = 0; 318 Error Err = Error::success(); 319 for (auto Child : Archive->children(Err)) { 320 if (auto ChildBuf = Child.getMemoryBufferRef()) { 321 if (auto Loadable = VisitMembers(*Archive, *ChildBuf, Index++)) { 322 if (!*Loadable) 323 Excluded.insert(Child.getDataOffset()); 324 } else 325 return Loadable.takeError(); 326 } else { 327 // We silently allow non-object archive members. This matches the 328 // behavior of ld. 329 consumeError(ChildBuf.takeError()); 330 } 331 } 332 if (Err) 333 return std::move(Err); 334 } 335 336 DenseMap<SymbolStringPtr, size_t> SymbolToMemberIndexMap; 337 { 338 DenseMap<uint64_t, size_t> OffsetToIndex; 339 size_t Index = 0; 340 Error Err = Error::success(); 341 for (auto &Child : Archive->children(Err)) { 342 // For all members not excluded above, add them to the OffsetToIndex map. 343 if (!Excluded.count(Child.getDataOffset())) 344 OffsetToIndex[Child.getDataOffset()] = Index; 345 ++Index; 346 } 347 if (Err) 348 return Err; 349 350 auto &ES = L.getExecutionSession(); 351 for (auto &Sym : Archive->symbols()) { 352 auto Member = Sym.getMember(); 353 if (!Member) 354 return Member.takeError(); 355 auto EntryItr = OffsetToIndex.find(Member->getDataOffset()); 356 357 // Missing entry means this member should be ignored. 358 if (EntryItr == OffsetToIndex.end()) 359 continue; 360 361 SymbolToMemberIndexMap[ES.intern(Sym.getName())] = EntryItr->second; 362 } 363 } 364 365 return std::unique_ptr<StaticLibraryDefinitionGenerator>( 366 new StaticLibraryDefinitionGenerator( 367 L, std::move(ArchiveBuffer), std::move(Archive), 368 std::move(GetObjFileInterface), std::move(SymbolToMemberIndexMap))); 369 } 370 371 Expected<std::unique_ptr<StaticLibraryDefinitionGenerator>> 372 StaticLibraryDefinitionGenerator::Create( 373 ObjectLayer &L, std::unique_ptr<MemoryBuffer> ArchiveBuffer, 374 VisitMembersFunction VisitMembers, 375 GetObjectFileInterface GetObjFileInterface) { 376 377 auto B = object::createBinary(ArchiveBuffer->getMemBufferRef()); 378 if (!B) 379 return B.takeError(); 380 381 // If this is a regular archive then create an instance from it. 382 if (isa<object::Archive>(*B)) 383 return Create(L, std::move(ArchiveBuffer), 384 std::unique_ptr<object::Archive>( 385 static_cast<object::Archive *>(B->release())), 386 std::move(VisitMembers), std::move(GetObjFileInterface)); 387 388 // If this is a universal binary then search for a slice matching the given 389 // Triple. 390 if (auto *UB = dyn_cast<object::MachOUniversalBinary>(B->get())) { 391 392 const auto &TT = L.getExecutionSession().getTargetTriple(); 393 394 auto SliceRange = getMachOSliceRangeForTriple(*UB, TT); 395 if (!SliceRange) 396 return SliceRange.takeError(); 397 398 MemoryBufferRef SliceRef( 399 StringRef(ArchiveBuffer->getBufferStart() + SliceRange->first, 400 SliceRange->second), 401 ArchiveBuffer->getBufferIdentifier()); 402 403 auto Archive = object::Archive::create(SliceRef); 404 if (!Archive) 405 return Archive.takeError(); 406 407 return Create(L, std::move(ArchiveBuffer), std::move(*Archive), 408 std::move(VisitMembers), std::move(GetObjFileInterface)); 409 } 410 411 return make_error<StringError>(Twine("Unrecognized file type for ") + 412 ArchiveBuffer->getBufferIdentifier(), 413 inconvertibleErrorCode()); 414 } 415 416 Error StaticLibraryDefinitionGenerator::tryToGenerate( 417 LookupState &LS, LookupKind K, JITDylib &JD, 418 JITDylibLookupFlags JDLookupFlags, const SymbolLookupSet &Symbols) { 419 // Don't materialize symbols from static archives unless this is a static 420 // lookup. 421 if (K != LookupKind::Static) 422 return Error::success(); 423 424 // Bail out early if we've already freed the archive. 425 if (!Archive) 426 return Error::success(); 427 428 DenseMap<size_t, MemoryBufferRef> ToLoad; 429 430 for (const auto &[Name, _] : Symbols) { 431 // Check whehter the archive contains this symbol. 432 auto It = SymbolToMemberIndexMap.find(Name); 433 if (It == SymbolToMemberIndexMap.end()) 434 continue; 435 size_t Index = It->second; 436 437 // If we're already loading the member containing this symbol then we're 438 // done. 439 if (ToLoad.count(Index)) 440 continue; 441 442 auto Member = Archive->findSym(*Name); 443 if (!Member) 444 return Member.takeError(); 445 if (!*Member) // Skip "none" children. 446 continue; 447 448 auto MemberBuf = (*Member)->getMemoryBufferRef(); 449 if (!MemberBuf) 450 return MemberBuf.takeError(); 451 452 ToLoad[Index] = *MemberBuf; 453 } 454 455 // Remove symbols to be loaded. 456 { 457 // FIXME: Enable DenseMap removal using NonOwningSymbolStringPtr? 458 std::vector<SymbolStringPtr> ToRemove; 459 for (auto &[Name, Index] : SymbolToMemberIndexMap) 460 if (ToLoad.count(Index)) 461 ToRemove.push_back(Name); 462 for (auto &Name : ToRemove) 463 SymbolToMemberIndexMap.erase(Name); 464 } 465 466 // Add loaded files to JITDylib. 467 for (auto &[Index, Buf] : ToLoad) { 468 auto MemberBuf = createMemberBuffer(*Archive, Buf, Index); 469 470 auto Interface = GetObjFileInterface(L.getExecutionSession(), 471 MemberBuf->getMemBufferRef()); 472 if (!Interface) 473 return Interface.takeError(); 474 475 if (auto Err = L.add(JD, std::move(MemberBuf), std::move(*Interface))) 476 return Err; 477 } 478 479 return Error::success(); 480 } 481 482 std::unique_ptr<MemoryBuffer> 483 StaticLibraryDefinitionGenerator::createMemberBuffer(object::Archive &A, 484 MemoryBufferRef BufRef, 485 size_t Index) { 486 return MemoryBuffer::getMemBuffer(BufRef.getBuffer(), 487 (A.getFileName() + "[" + Twine(Index) + 488 "](" + BufRef.getBufferIdentifier() + ")") 489 .str(), 490 false); 491 } 492 493 StaticLibraryDefinitionGenerator::StaticLibraryDefinitionGenerator( 494 ObjectLayer &L, std::unique_ptr<MemoryBuffer> ArchiveBuffer, 495 std::unique_ptr<object::Archive> Archive, 496 GetObjectFileInterface GetObjFileInterface, 497 DenseMap<SymbolStringPtr, size_t> SymbolToMemberIndexMap) 498 : L(L), GetObjFileInterface(std::move(GetObjFileInterface)), 499 ArchiveBuffer(std::move(ArchiveBuffer)), Archive(std::move(Archive)), 500 SymbolToMemberIndexMap(std::move(SymbolToMemberIndexMap)) { 501 if (!this->GetObjFileInterface) 502 this->GetObjFileInterface = getObjectFileInterface; 503 } 504 505 std::unique_ptr<DLLImportDefinitionGenerator> 506 DLLImportDefinitionGenerator::Create(ExecutionSession &ES, 507 ObjectLinkingLayer &L) { 508 return std::unique_ptr<DLLImportDefinitionGenerator>( 509 new DLLImportDefinitionGenerator(ES, L)); 510 } 511 512 Error DLLImportDefinitionGenerator::tryToGenerate( 513 LookupState &LS, LookupKind K, JITDylib &JD, 514 JITDylibLookupFlags JDLookupFlags, const SymbolLookupSet &Symbols) { 515 JITDylibSearchOrder LinkOrder; 516 JD.withLinkOrderDo([&](const JITDylibSearchOrder &LO) { 517 LinkOrder.reserve(LO.size()); 518 for (auto &KV : LO) { 519 if (KV.first == &JD) 520 continue; 521 LinkOrder.push_back(KV); 522 } 523 }); 524 525 // FIXME: if regular symbol name start with __imp_ we have to issue lookup of 526 // both __imp_ and stripped name and use the lookup information to resolve the 527 // real symbol name. 528 SymbolLookupSet LookupSet; 529 DenseMap<StringRef, SymbolLookupFlags> ToLookUpSymbols; 530 for (auto &KV : Symbols) { 531 StringRef Deinterned = *KV.first; 532 if (Deinterned.starts_with(getImpPrefix())) 533 Deinterned = Deinterned.drop_front(StringRef(getImpPrefix()).size()); 534 // Don't degrade the required state 535 auto [It, Inserted] = ToLookUpSymbols.try_emplace(Deinterned); 536 if (Inserted || It->second != SymbolLookupFlags::RequiredSymbol) 537 It->second = KV.second; 538 } 539 540 for (auto &KV : ToLookUpSymbols) 541 LookupSet.add(ES.intern(KV.first), KV.second); 542 543 auto Resolved = ES.lookup(LinkOrder, LookupSet, LookupKind::Static, 544 SymbolState::Resolved); 545 if (!Resolved) 546 return Resolved.takeError(); 547 548 auto G = createStubsGraph(*Resolved); 549 if (!G) 550 return G.takeError(); 551 return L.add(JD, std::move(*G)); 552 } 553 554 Expected<std::unique_ptr<jitlink::LinkGraph>> 555 DLLImportDefinitionGenerator::createStubsGraph(const SymbolMap &Resolved) { 556 auto G = std::make_unique<jitlink::LinkGraph>( 557 "<DLLIMPORT_STUBS>", ES.getSymbolStringPool(), ES.getTargetTriple(), 558 SubtargetFeatures(), jitlink::getGenericEdgeKindName); 559 jitlink::Section &Sec = 560 G->createSection(getSectionName(), MemProt::Read | MemProt::Exec); 561 562 for (auto &KV : Resolved) { 563 jitlink::Symbol &Target = G->addAbsoluteSymbol( 564 *KV.first, KV.second.getAddress(), G->getPointerSize(), 565 jitlink::Linkage::Strong, jitlink::Scope::Local, false); 566 567 // Create __imp_ symbol 568 jitlink::Symbol &Ptr = 569 jitlink::x86_64::createAnonymousPointer(*G, Sec, &Target); 570 Ptr.setName(G->intern((Twine(getImpPrefix()) + *KV.first).str())); 571 Ptr.setLinkage(jitlink::Linkage::Strong); 572 Ptr.setScope(jitlink::Scope::Default); 573 574 // Create PLT stub 575 // FIXME: check PLT stub of data symbol is not accessed 576 jitlink::Block &StubBlock = 577 jitlink::x86_64::createPointerJumpStubBlock(*G, Sec, Ptr); 578 G->addDefinedSymbol(StubBlock, 0, *KV.first, StubBlock.getSize(), 579 jitlink::Linkage::Strong, jitlink::Scope::Default, true, 580 false); 581 } 582 583 return std::move(G); 584 } 585 586 } // End namespace orc. 587 } // End namespace llvm. 588