1//===- Core/Resolver.h - Resolves Atom References -------------------------===// 2// 3// The LLVM Linker 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9 10#ifndef LLD_CORE_RESOLVER_H 11#define LLD_CORE_RESOLVER_H 12 13#include "lld/Core/ArchiveLibraryFile.h" 14#include "lld/Core/File.h" 15#include "lld/Core/SharedLibraryFile.h" 16#include "lld/Core/Simple.h" 17#include "lld/Core/SymbolTable.h" 18#include "llvm/ADT/DenseMap.h" 19#include "llvm/ADT/DenseSet.h" 20#include "llvm/Support/ErrorOr.h" 21#include <set> 22#include <unordered_map> 23#include <unordered_set> 24#include <vector> 25 26namespace lld { 27 28class Atom; 29class LinkingContext; 30 31/// \brief The Resolver is responsible for merging all input object files 32/// and producing a merged graph. 33class Resolver { 34public: 35 Resolver(LinkingContext &ctx) : _ctx(ctx), _result(new MergedFile()) {} 36 37 // InputFiles::Handler methods 38 void doDefinedAtom(OwningAtomPtr<DefinedAtom> atom); 39 bool doUndefinedAtom(OwningAtomPtr<UndefinedAtom> atom); 40 void doSharedLibraryAtom(OwningAtomPtr<SharedLibraryAtom> atom); 41 void doAbsoluteAtom(OwningAtomPtr<AbsoluteAtom> atom); 42 43 // Handle files, this adds atoms from the current file thats 44 // being processed by the resolver 45 llvm::Expected<bool> handleFile(File &); 46 47 // Handle an archive library file. 48 llvm::Expected<bool> handleArchiveFile(File &); 49 50 // Handle a shared library file. 51 llvm::Error handleSharedLibrary(File &); 52 53 /// @brief do work of merging and resolving and return list 54 bool resolve(); 55 56 std::unique_ptr<SimpleFile> resultFile() { return std::move(_result); } 57 58private: 59 typedef std::function<llvm::Expected<bool>(StringRef)> UndefCallback; 60 61 bool undefinesAdded(int begin, int end); 62 File *getFile(int &index); 63 64 /// \brief The main function that iterates over the files to resolve 65 bool resolveUndefines(); 66 void updateReferences(); 67 void deadStripOptimize(); 68 bool checkUndefines(); 69 void removeCoalescedAwayAtoms(); 70 llvm::Expected<bool> forEachUndefines(File &file, UndefCallback callback); 71 72 void markLive(const Atom *atom); 73 74 class MergedFile : public SimpleFile { 75 public: 76 MergedFile() : SimpleFile("<linker-internal>", kindResolverMergedObject) {} 77 void addAtoms(llvm::MutableArrayRef<OwningAtomPtr<Atom>> atoms); 78 }; 79 80 LinkingContext &_ctx; 81 SymbolTable _symbolTable; 82 std::vector<OwningAtomPtr<Atom>> _atoms; 83 std::set<const Atom *> _deadStripRoots; 84 llvm::DenseSet<const Atom *> _liveAtoms; 85 llvm::DenseSet<const Atom *> _deadAtoms; 86 std::unique_ptr<MergedFile> _result; 87 std::unordered_multimap<const Atom *, const Atom *> _reverseRef; 88 89 // --start-group and --end-group 90 std::vector<File *> _files; 91 std::map<File *, bool> _newUndefinesAdded; 92 93 // List of undefined symbols. 94 std::vector<StringRef> _undefines; 95 96 // Start position in _undefines for each archive/shared library file. 97 // Symbols from index 0 to the start position are already searched before. 98 // Searching them again would never succeed. When we look for undefined 99 // symbols from an archive/shared library file, start from its start 100 // position to save time. 101 std::map<File *, size_t> _undefineIndex; 102}; 103 104} // namespace lld 105 106#endif // LLD_CORE_RESOLVER_H 107