blob: 5157c9fddc1a2eea4df49cb32afd7d777cdd7cd8 [file] [log] [blame]
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01001//===- 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
Andrew Scullcdfcccc2018-10-05 20:58:37 +010031/// The Resolver is responsible for merging all input object files
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010032/// 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
Andrew Scullcdfcccc2018-10-05 20:58:37 +010053 /// do work of merging and resolving and return list
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010054 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
Andrew Scullcdfcccc2018-10-05 20:58:37 +010064 /// The main function that iterates over the files to resolve
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010065 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