29#define DEBUG_TYPE "orc-resolver" 
   35      LibPathResolver(S.PResolver
 
   38      ScanHelper(S.BasePaths, LibPathCache, LibPathResolver),
 
   39      FB(S.FilterBuilder), LibMgr(),
 
   40      ShouldScanCall(S.ShouldScanCall ? S.ShouldScanCall
 
   42      scanBatchSize(S.ScanBatchSize) {
 
   44  if (ScanHelper.getAllUnits().empty()) {
 
   45    LLVM_DEBUG(
dbgs() << 
"Warning: No base paths provided for scanning.\n");
 
 
   49std::unique_ptr<LibraryResolutionDriver>
 
   51  auto LR = std::make_unique<LibraryResolver>(S);
 
   52  return std::unique_ptr<LibraryResolutionDriver>(
 
   53      new LibraryResolutionDriver(std::move(LR)));
 
 
   57  LR->ScanHelper.addBasePath(Path, K);
 
 
   61  auto Lib = LR->LibMgr.getLibrary(Path);
 
 
   71  auto Lib = LR->LibMgr.getLibrary(Path);
 
 
   81    std::vector<std::string> Syms,
 
   84  LR->searchSymbolsInLibraries(Syms, std::move(OnCompletion), Config);
 
 
   98  if ((IgnoreFlags & Filter::IgnoreUndefined) &&
 
  101  if ((IgnoreFlags & Filter::IgnoreIndirect) &&
 
  104  if ((IgnoreFlags & Filter::IgnoreWeak) &&
 
 
  124                      << 
"\nError: " << ErrMsg << 
"\n");
 
  130  auto processSymbolRange =
 
  132    for (
const auto &Sym : 
Range) {
 
  136      auto NameOrErr = Sym.getName();
 
  147      if (Res != EnumerateResult::Continue)
 
  150    return EnumerateResult::Continue;
 
  154  if (Res != EnumerateResult::Continue)
 
  155    return Res == EnumerateResult::Stop;
 
  159    Res = processSymbolRange(ElfObj->getDynamicSymbolIterators());
 
  160    if (Res != EnumerateResult::Continue)
 
  161      return Res == EnumerateResult::Stop;
 
  162  } 
else if (Obj->
isCOFF()) {
 
  164    for (
auto I = CoffObj->export_directory_begin(),
 
  165              E = CoffObj->export_directory_end();
 
  168      if (
I->getSymbolName(Name))
 
  174      if (Res != EnumerateResult::Continue)
 
  175        return Res == EnumerateResult::Stop;
 
 
  200void LibraryResolver::resolveSymbolsInLibrary(
 
  201    LibraryInfo &
Lib, SymbolQuery &UnresolvedSymbols,
 
  202    const SymbolEnumeratorOptions &Opts) {
 
  204                    << 
" in library : " << 
Lib.getFileName() << 
"\n";);
 
  207  if (!UnresolvedSymbols.hasUnresolved()) {
 
  209                      << 
" — unresolved symbols exist.\n";);
 
  213  bool HasEnumerated = 
false;
 
  214  auto enumerateSymbolsIfNeeded = [&]() {
 
  218    HasEnumerated = 
true;
 
  220    LLVM_DEBUG(dbgs() << 
"Enumerating symbols in library: " << Lib.getFullPath()
 
  222    SymbolEnumerator::enumerateSymbols(
 
  225          DiscoveredSymbols.insert(sym);
 
  226          return EnumerateResult::Continue;
 
  230    if (DiscoveredSymbols.
empty()) {
 
  231      LLVM_DEBUG(dbgs() << 
"  No symbols and remove library : " 
  232                        << Lib.getFullPath() << 
"\n";);
 
  233      LibMgr.removeLibrary(Lib.getFullPath());
 
  238  if (!
Lib.hasFilter()) {
 
  241    enumerateSymbolsIfNeeded();
 
  242    SmallVector<StringRef> SymbolVec;
 
  243    SymbolVec.reserve(DiscoveredSymbols.
size());
 
  244    for (
const auto &KV : DiscoveredSymbols)
 
  245      SymbolVec.push_back(KV.first());
 
  247    Lib.ensureFilterBuilt(FB, SymbolVec);
 
  249      dbgs() << 
"DiscoveredSymbols : " << DiscoveredSymbols.size() << 
"\n";
 
  250      for (
const auto &KV : DiscoveredSymbols)
 
  251        dbgs() << 
"DiscoveredSymbols : " << KV.first() << 
"\n";
 
  255  const auto &Unresolved = UnresolvedSymbols.getUnresolvedSymbols();
 
  256  bool HadAnySym = 
false;
 
  257  LLVM_DEBUG(
dbgs() << 
"Total unresolved symbols : " << Unresolved.size()
 
  259  for (
const auto &Sym : Unresolved) {
 
  260    if (
Lib.mayContain(Sym)) {
 
  262                        << 
"' in library: " << 
Lib.getFullPath() << 
"\n";);
 
  263      enumerateSymbolsIfNeeded();
 
  264      if (DiscoveredSymbols.count(Sym) > 0) {
 
  266                          << 
" in library: " << 
Lib.getFullPath() << 
"\n";);
 
  267        UnresolvedSymbols.resolve(Sym, 
Lib.getFullPath());
 
  273  using LibraryState = LibraryManager::LibState;
 
  274  if (HadAnySym && 
Lib.getState() != LibraryState::Loaded)
 
  275    Lib.setState(LibraryState::Queried);
 
  285  auto tryResolveFrom = [&](LibraryState S, LibraryType K) {
 
  286    LLVM_DEBUG(
dbgs() << 
"Trying resolve from state=" << 
static_cast<int>(S)
 
  287                      << 
" type=" << 
static_cast<int>(K) << 
"\n";);
 
  290    while (!Ctx.allResolved()) {
 
  292      for (
auto &
Lib : LibMgr.getView(S, K)) {
 
  293        if (Ctx.hasSearched(
Lib.get()))
 
  297        resolveSymbolsInLibrary(*
Lib, Ctx.query(), Config.
Options);
 
  298        Ctx.markSearched(
Lib.get());
 
  300        if (Ctx.allResolved())
 
  304      if (Ctx.allResolved())
 
  307      if (!scanLibrariesIfNeeded(K, scanBatchSize))
 
  312  for (
const auto &[St, Ty] : Config.
Policy.
Plan) {
 
  313    tryResolveFrom(St, Ty);
 
  320    dbgs() << 
"Search complete.\n";
 
  322      dbgs() << 
"Resolved Symbol:" << r->Name << 
" -> " << r->ResolvedLibPath
 
 
  329bool LibraryResolver::scanLibrariesIfNeeded(
PathType PK, 
size_t BatchSize) {
 
  330  LLVM_DEBUG(
dbgs() << 
"LibraryResolver::scanLibrariesIfNeeded: Scanning for " 
  331                    << (PK == PathType::User ? 
"User" : 
"System")
 
  333  if (!ScanHelper.leftToScan(PK))
 
  337  Scanner.scanNext(PK, BatchSize);
 
  341bool LibraryResolver::symbolExistsInLibrary(
const LibraryInfo &
Lib,
 
  343                                            std::vector<std::string> *AllSyms) {
 
  344  SymbolEnumeratorOptions Opts;
 
  345  return symbolExistsInLibrary(
Lib, SymName, AllSyms, Opts);
 
  348bool LibraryResolver::symbolExistsInLibrary(
 
  349    const LibraryInfo &Lib, StringRef SymName,
 
  350    std::vector<std::string> *AllSyms, 
const SymbolEnumeratorOptions &Opts) {
 
  353  SymbolEnumerator::enumerateSymbols(
 
  357          AllSyms->emplace_back(Sym.str());
 
  359        if (Sym == SymName) {
 
  363        return EnumerateResult::Continue;
 
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
 
ConstantRange Range(APInt(BitWidth, Low), APInt(BitWidth, High))
 
StringSet - A set-like wrapper for the StringMap.
 
Implements a dense probed hash-table based set.
 
Base class for error info classes.
 
Tagged union holding either a T or a Error.
 
Error takeError()
Take ownership of the stored error.
 
StringRef - Represent a constant reference to a string, i.e.
 
StringSet - A wrapper for StringMap that provides set-like functionality.
 
Expected< uint32_t > getFlags() const
Get symbol flags (bitwise OR of SymbolRef::Flags)
 
This class is the base class for all object file types.
 
symbol_iterator_range symbols() const
 
iterator_range< symbol_iterator > symbol_iterator_range
 
This is a value type class that represents a single symbol in the list of symbols in the object file.
 
void resolveSymbols(std::vector< std::string > Symbols, LibraryResolver::OnSearchComplete OnCompletion, const SearchConfig &Config=SearchConfig())
 
void addScanPath(const std::string &Path, PathType Kind)
 
bool markLibraryLoaded(StringRef Path)
 
static std::unique_ptr< LibraryResolutionDriver > create(const LibraryResolver::Setup &S)
 
bool markLibraryUnLoaded(StringRef Path)
 
std::function< EnumerateResult(StringRef Sym)> OnEachSymbolFn
 
static bool enumerateSymbols(StringRef Path, OnEachSymbolFn OnEach, const SymbolEnumeratorOptions &Opts)
 
Tracks a set of symbols and the libraries where they are resolved.
 
std::vector< const Result * > getAllResults() const
 
unique_function< void(SymbolQuery &)> OnSearchComplete
 
void searchSymbolsInLibraries(std::vector< std::string > &SymList, OnSearchComplete OnComplete, const SearchConfig &Config=SearchConfig())
 
Scans libraries, resolves dependencies, and registers them.
 
Loads an object file and provides access to it.
 
Expected< object::ObjectFile & > getObjectFile()
Get the loaded object file, or return an error if loading failed.
 
Resolves file system paths with optional caching of results.
 
bool hasSearched(LibraryInfo *Lib) const
 
void markSearched(LibraryInfo *Lib)
 
SymbolSearchContext(SymbolQuery &Q)
 
LibraryManager::LibraryInfo LibraryInfo
 
static bool shouldIgnoreSymbol(const object::SymbolRef &Sym, uint32_t IgnoreFlags)
 
LibraryResolver::SymbolQuery SymbolQuery
 
void handleAllErrors(Error E, HandlerTs &&... Handlers)
Behaves the same as handleErrors, except that by contract all errors must be handled by the given han...
 
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
 
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
 
void consumeError(Error Err)
Consume a Error without doing anything.
 
Implement std::hash so that hash_code can be used in STL containers.
 
SymbolEnumeratorOptions Options
 
std::vector< SearchPlanEntry > Plan