Resolver.h revision 353358
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
25namespace lld {
26
27class Atom;
28class LinkingContext;
29
30/// The Resolver is responsible for merging all input object files
31/// and producing a merged graph.
32class Resolver {
33public:
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
55  std::unique_ptr<SimpleFile> resultFile() { return std::move(_result); }
56
57private:
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:
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