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