1 //===---------------- EPCDynamicLibrarySearchGenerator.cpp ----------------===// 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/EPCDynamicLibrarySearchGenerator.h" 10 11 #include "llvm/ExecutionEngine/Orc/AbsoluteSymbols.h" 12 #include "llvm/ExecutionEngine/Orc/DebugUtils.h" 13 #include "llvm/Support/Error.h" 14 15 #define DEBUG_TYPE "orc" 16 17 namespace llvm { 18 namespace orc { 19 20 Expected<std::unique_ptr<EPCDynamicLibrarySearchGenerator>> 21 EPCDynamicLibrarySearchGenerator::Load( 22 ExecutionSession &ES, const char *LibraryPath, SymbolPredicate Allow, 23 AddAbsoluteSymbolsFn AddAbsoluteSymbols) { 24 auto Handle = 25 ES.getExecutorProcessControl().getDylibMgr().loadDylib(LibraryPath); 26 if (!Handle) 27 return Handle.takeError(); 28 29 return std::make_unique<EPCDynamicLibrarySearchGenerator>( 30 ES, *Handle, std::move(Allow), std::move(AddAbsoluteSymbols)); 31 } 32 33 Error EPCDynamicLibrarySearchGenerator::tryToGenerate( 34 LookupState &LS, LookupKind K, JITDylib &JD, 35 JITDylibLookupFlags JDLookupFlags, const SymbolLookupSet &Symbols) { 36 37 if (Symbols.empty()) 38 return Error::success(); 39 40 LLVM_DEBUG({ 41 dbgs() << "EPCDynamicLibrarySearchGenerator trying to generate " 42 << Symbols << "\n"; 43 }); 44 45 // If there's no handle then resolve all requested symbols to null. 46 if (!H) { 47 assert(Allow && "No handle or filter?"); 48 SymbolMap Nulls; 49 for (auto &[Name, LookupFlags] : Symbols) { 50 if (Allow(Name)) 51 Nulls[Name] = {}; 52 } 53 return addAbsolutes(JD, std::move(Nulls)); 54 } 55 56 // Otherwise proceed with lookup in the remote. 57 SymbolLookupSet LookupSymbols; 58 59 for (auto &KV : Symbols) { 60 // Skip symbols that don't match the filter. 61 if (Allow && !Allow(KV.first)) 62 continue; 63 LookupSymbols.add(KV.first, SymbolLookupFlags::WeaklyReferencedSymbol); 64 } 65 66 DylibManager::LookupRequest Request(*H, LookupSymbols); 67 // Copy-capture LookupSymbols, since LookupRequest keeps a reference. 68 EPC.getDylibMgr().lookupSymbolsAsync(Request, [this, &JD, LS = std::move(LS), 69 LookupSymbols]( 70 auto Result) mutable { 71 if (!Result) { 72 LLVM_DEBUG({ 73 dbgs() << "EPCDynamicLibrarySearchGenerator lookup failed due to error"; 74 }); 75 return LS.continueLookup(Result.takeError()); 76 } 77 78 assert(Result->size() == 1 && "Results for more than one library returned"); 79 assert(Result->front().size() == LookupSymbols.size() && 80 "Result has incorrect number of elements"); 81 82 SymbolMap NewSymbols; 83 auto ResultI = Result->front().begin(); 84 for (auto &KV : LookupSymbols) { 85 if (ResultI->getAddress()) 86 NewSymbols[KV.first] = *ResultI; 87 ++ResultI; 88 } 89 90 LLVM_DEBUG({ 91 dbgs() << "EPCDynamicLibrarySearchGenerator lookup returned " 92 << NewSymbols << "\n"; 93 }); 94 95 // If there were no resolved symbols bail out. 96 if (NewSymbols.empty()) 97 return LS.continueLookup(Error::success()); 98 99 // Define resolved symbols. 100 Error Err = addAbsolutes(JD, std::move(NewSymbols)); 101 102 LS.continueLookup(std::move(Err)); 103 }); 104 105 return Error::success(); 106 } 107 108 Error EPCDynamicLibrarySearchGenerator::addAbsolutes(JITDylib &JD, 109 SymbolMap Symbols) { 110 return AddAbsoluteSymbols ? AddAbsoluteSymbols(JD, std::move(Symbols)) 111 : JD.define(absoluteSymbols(std::move(Symbols))); 112 } 113 114 } // end namespace orc 115 } // end namespace llvm 116