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