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