124 lines · cpp
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-exception6//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 17namespace llvm {18namespace orc {19 20Expected<std::unique_ptr<EPCDynamicLibrarySearchGenerator>>21EPCDynamicLibrarySearchGenerator::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 33Error 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 auto SymsIt = Result->front().begin();83 SymbolNameSet MissingSymbols;84 SymbolMap NewSymbols;85 for (auto &[Name, Flags] : LookupSymbols) {86 const auto &Sym = *SymsIt++;87 if (Sym && Sym->getAddress())88 NewSymbols[Name] = *Sym;89 else if (LLVM_UNLIKELY(!Sym &&90 Flags == SymbolLookupFlags::RequiredSymbol))91 MissingSymbols.insert(Name);92 }93 94 LLVM_DEBUG({95 dbgs() << "EPCDynamicLibrarySearchGenerator lookup returned "96 << NewSymbols << "\n";97 });98 99 // If there were no resolved symbols bail out.100 if (NewSymbols.empty())101 return LS.continueLookup(Error::success());102 103 if (LLVM_UNLIKELY(!MissingSymbols.empty()))104 return LS.continueLookup(make_error<SymbolsNotFound>(105 this->EPC.getSymbolStringPool(), std::move(MissingSymbols)));106 107 // Define resolved symbols.108 Error Err = addAbsolutes(JD, std::move(NewSymbols));109 110 LS.continueLookup(std::move(Err));111 });112 113 return Error::success();114}115 116Error EPCDynamicLibrarySearchGenerator::addAbsolutes(JITDylib &JD,117 SymbolMap Symbols) {118 return AddAbsoluteSymbols ? AddAbsoluteSymbols(JD, std::move(Symbols))119 : JD.define(absoluteSymbols(std::move(Symbols)));120}121 122} // end namespace orc123} // end namespace llvm124