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 26 namespace lld { 27 28 class Atom; 29 class LinkingContext; 30 31 /// \brief The Resolver is responsible for merging all input object files 32 /// and producing a merged graph. 33 class Resolver { 34 public: 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 58 private: 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