1fe6060f1SDimitry Andric //===---------------- EPCDynamicLibrarySearchGenerator.cpp ----------------===// 2fe6060f1SDimitry Andric // 3fe6060f1SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4fe6060f1SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 5fe6060f1SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6fe6060f1SDimitry Andric // 7fe6060f1SDimitry Andric //===----------------------------------------------------------------------===// 8fe6060f1SDimitry Andric 9fe6060f1SDimitry Andric #include "llvm/ExecutionEngine/Orc/EPCDynamicLibrarySearchGenerator.h" 10*0fca6ea1SDimitry Andric #include "llvm/ExecutionEngine/Orc/DebugUtils.h" 11*0fca6ea1SDimitry Andric #include "llvm/Support/Error.h" 12*0fca6ea1SDimitry Andric 13*0fca6ea1SDimitry Andric #define DEBUG_TYPE "orc" 14fe6060f1SDimitry Andric 15fe6060f1SDimitry Andric namespace llvm { 16fe6060f1SDimitry Andric namespace orc { 17fe6060f1SDimitry Andric 18fe6060f1SDimitry Andric Expected<std::unique_ptr<EPCDynamicLibrarySearchGenerator>> 191db9f3b2SDimitry Andric EPCDynamicLibrarySearchGenerator::Load( 201db9f3b2SDimitry Andric ExecutionSession &ES, const char *LibraryPath, SymbolPredicate Allow, 211db9f3b2SDimitry Andric AddAbsoluteSymbolsFn AddAbsoluteSymbols) { 22fe6060f1SDimitry Andric auto Handle = ES.getExecutorProcessControl().loadDylib(LibraryPath); 23fe6060f1SDimitry Andric if (!Handle) 24fe6060f1SDimitry Andric return Handle.takeError(); 25fe6060f1SDimitry Andric 261db9f3b2SDimitry Andric return std::make_unique<EPCDynamicLibrarySearchGenerator>( 271db9f3b2SDimitry Andric ES, *Handle, std::move(Allow), std::move(AddAbsoluteSymbols)); 28fe6060f1SDimitry Andric } 29fe6060f1SDimitry Andric 30fe6060f1SDimitry Andric Error EPCDynamicLibrarySearchGenerator::tryToGenerate( 31fe6060f1SDimitry Andric LookupState &LS, LookupKind K, JITDylib &JD, 32fe6060f1SDimitry Andric JITDylibLookupFlags JDLookupFlags, const SymbolLookupSet &Symbols) { 33fe6060f1SDimitry Andric 34fe6060f1SDimitry Andric if (Symbols.empty()) 35fe6060f1SDimitry Andric return Error::success(); 36fe6060f1SDimitry Andric 37*0fca6ea1SDimitry Andric LLVM_DEBUG({ 38*0fca6ea1SDimitry Andric dbgs() << "EPCDynamicLibrarySearchGenerator trying to generate " 39*0fca6ea1SDimitry Andric << Symbols << "\n"; 40*0fca6ea1SDimitry Andric }); 41*0fca6ea1SDimitry Andric 42fe6060f1SDimitry Andric SymbolLookupSet LookupSymbols; 43fe6060f1SDimitry Andric 44fe6060f1SDimitry Andric for (auto &KV : Symbols) { 45fe6060f1SDimitry Andric // Skip symbols that don't match the filter. 46fe6060f1SDimitry Andric if (Allow && !Allow(KV.first)) 47fe6060f1SDimitry Andric continue; 48fe6060f1SDimitry Andric LookupSymbols.add(KV.first, SymbolLookupFlags::WeaklyReferencedSymbol); 49fe6060f1SDimitry Andric } 50fe6060f1SDimitry Andric 51fe6060f1SDimitry Andric ExecutorProcessControl::LookupRequest Request(H, LookupSymbols); 52*0fca6ea1SDimitry Andric // Copy-capture LookupSymbols, since LookupRequest keeps a reference. 53*0fca6ea1SDimitry Andric EPC.lookupSymbolsAsync(Request, [this, &JD, LS = std::move(LS), 54*0fca6ea1SDimitry Andric LookupSymbols](auto Result) mutable { 55*0fca6ea1SDimitry Andric if (!Result) { 56*0fca6ea1SDimitry Andric LLVM_DEBUG({ 57*0fca6ea1SDimitry Andric dbgs() << "EPCDynamicLibrarySearchGenerator lookup failed due to error"; 58*0fca6ea1SDimitry Andric }); 59*0fca6ea1SDimitry Andric return LS.continueLookup(Result.takeError()); 60*0fca6ea1SDimitry Andric } 61fe6060f1SDimitry Andric 62fe6060f1SDimitry Andric assert(Result->size() == 1 && "Results for more than one library returned"); 63fe6060f1SDimitry Andric assert(Result->front().size() == LookupSymbols.size() && 64fe6060f1SDimitry Andric "Result has incorrect number of elements"); 65fe6060f1SDimitry Andric 66*0fca6ea1SDimitry Andric SymbolMap NewSymbols; 67fe6060f1SDimitry Andric auto ResultI = Result->front().begin(); 68fe6060f1SDimitry Andric for (auto &KV : LookupSymbols) { 691db9f3b2SDimitry Andric if (ResultI->getAddress()) 701db9f3b2SDimitry Andric NewSymbols[KV.first] = *ResultI; 71fe6060f1SDimitry Andric ++ResultI; 72fe6060f1SDimitry Andric } 73fe6060f1SDimitry Andric 74*0fca6ea1SDimitry Andric LLVM_DEBUG({ 75*0fca6ea1SDimitry Andric dbgs() << "EPCDynamicLibrarySearchGenerator lookup returned " 76*0fca6ea1SDimitry Andric << NewSymbols << "\n"; 77*0fca6ea1SDimitry Andric }); 78*0fca6ea1SDimitry Andric 79fe6060f1SDimitry Andric // If there were no resolved symbols bail out. 80fe6060f1SDimitry Andric if (NewSymbols.empty()) 81*0fca6ea1SDimitry Andric return LS.continueLookup(Error::success()); 82fe6060f1SDimitry Andric 83fe6060f1SDimitry Andric // Define resolved symbols. 84*0fca6ea1SDimitry Andric Error Err = AddAbsoluteSymbols 85*0fca6ea1SDimitry Andric ? AddAbsoluteSymbols(JD, std::move(NewSymbols)) 86*0fca6ea1SDimitry Andric : JD.define(absoluteSymbols(std::move(NewSymbols))); 87*0fca6ea1SDimitry Andric 88*0fca6ea1SDimitry Andric LS.continueLookup(std::move(Err)); 89*0fca6ea1SDimitry Andric }); 90*0fca6ea1SDimitry Andric 91*0fca6ea1SDimitry Andric return Error::success(); 92fe6060f1SDimitry Andric } 93fe6060f1SDimitry Andric 94fe6060f1SDimitry Andric } // end namespace orc 95fe6060f1SDimitry Andric } // end namespace llvm 96