Home | History | Annotate | Download | only in Core
      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