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 SymbolLookupSet LookupSymbols; 46 47 for (auto &KV : Symbols) { 48 // Skip symbols that don't match the filter. 49 if (Allow && !Allow(KV.first)) 50 continue; 51 LookupSymbols.add(KV.first, SymbolLookupFlags::WeaklyReferencedSymbol); 52 } 53 54 DylibManager::LookupRequest Request(H, LookupSymbols); 55 // Copy-capture LookupSymbols, since LookupRequest keeps a reference. 56 EPC.getDylibMgr().lookupSymbolsAsync(Request, [this, &JD, LS = std::move(LS), 57 LookupSymbols]( 58 auto Result) mutable { 59 if (!Result) { 60 LLVM_DEBUG({ 61 dbgs() << "EPCDynamicLibrarySearchGenerator lookup failed due to error"; 62 }); 63 return LS.continueLookup(Result.takeError()); 64 } 65 66 assert(Result->size() == 1 && "Results for more than one library returned"); 67 assert(Result->front().size() == LookupSymbols.size() && 68 "Result has incorrect number of elements"); 69 70 SymbolMap NewSymbols; 71 auto ResultI = Result->front().begin(); 72 for (auto &KV : LookupSymbols) { 73 if (ResultI->getAddress()) 74 NewSymbols[KV.first] = *ResultI; 75 ++ResultI; 76 } 77 78 LLVM_DEBUG({ 79 dbgs() << "EPCDynamicLibrarySearchGenerator lookup returned " 80 << NewSymbols << "\n"; 81 }); 82 83 // If there were no resolved symbols bail out. 84 if (NewSymbols.empty()) 85 return LS.continueLookup(Error::success()); 86 87 // Define resolved symbols. 88 Error Err = AddAbsoluteSymbols 89 ? AddAbsoluteSymbols(JD, std::move(NewSymbols)) 90 : JD.define(absoluteSymbols(std::move(NewSymbols))); 91 92 LS.continueLookup(std::move(Err)); 93 }); 94 95 return Error::success(); 96 } 97 98 } // end namespace orc 99 } // end namespace llvm 100