Coverage Report

Created: 2017-10-03 07:32

/Users/buildslave/jenkins/sharedspace/clang-stage2-coverage-R@2/llvm/tools/lld/include/lld/Core/LinkingContext.h
Line
Count
Source (jump to first uncovered line)
1
//===- lld/Core/LinkingContext.h - Linker Target Info Interface -*- C++ -*-===//
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_LINKING_CONTEXT_H
11
#define LLD_CORE_LINKING_CONTEXT_H
12
13
#include "lld/Core/Node.h"
14
#include "lld/Core/Reader.h"
15
#include "llvm/ADT/ArrayRef.h"
16
#include "llvm/ADT/StringRef.h"
17
#include "llvm/Support/Allocator.h"
18
#include "llvm/Support/Error.h"
19
#include "llvm/Support/raw_ostream.h"
20
#include <cassert>
21
#include <cstdint>
22
#include <memory>
23
#include <string>
24
#include <vector>
25
26
namespace lld {
27
28
class PassManager;
29
class File;
30
class Writer;
31
class Node;
32
class SharedLibraryFile;
33
34
/// \brief The LinkingContext class encapsulates "what and how" to link.
35
///
36
/// The base class LinkingContext contains the options needed by core linking.
37
/// Subclasses of LinkingContext have additional options needed by specific
38
/// Writers.
39
class LinkingContext {
40
public:
41
  virtual ~LinkingContext();
42
43
  /// \name Methods needed by core linking
44
  /// @{
45
46
  /// Name of symbol linker should use as "entry point" to program,
47
  /// usually "main" or "start".
48
370
  virtual StringRef entrySymbolName() const { return _entrySymbolName; }
49
50
  /// Whether core linking should remove Atoms not reachable by following
51
  /// References from the entry point Atom or from all global scope Atoms
52
  /// if globalsAreDeadStripRoots() is true.
53
1.32k
  bool deadStrip() const { return _deadStrip; }
54
55
  /// Only used if deadStrip() returns true.  Means all global scope Atoms
56
  /// should be marked live (along with all Atoms they reference).  Usually
57
  /// this method returns false for main executables, but true for dynamic
58
  /// shared libraries.
59
13
  bool globalsAreDeadStripRoots() const { return _globalsAreDeadStripRoots; }
60
61
  /// Only used if deadStrip() returns true.  This method returns the names
62
  /// of DefinedAtoms that should be marked live (along with all Atoms they
63
  /// reference). Only Atoms with scope scopeLinkageUnit or scopeGlobal can
64
  /// be kept live using this method.
65
7
  const std::vector<StringRef> &deadStripRoots() const {
66
7
    return _deadStripRoots;
67
7
  }
68
69
  /// Add the given symbol name to the dead strip root set. Only used if
70
  /// deadStrip() returns true.
71
19
  void addDeadStripRoot(StringRef symbolName) {
72
19
    assert(!symbolName.empty() && "Empty symbol cannot be a dead strip root");
73
19
    _deadStripRoots.push_back(symbolName);
74
19
  }
75
76
  /// Normally, every UndefinedAtom must be replaced by a DefinedAtom or a
77
  /// SharedLibraryAtom for the link to be successful.  This method controls
78
  /// whether core linking prints out a list of remaining UndefinedAtoms.
79
  ///
80
  /// \todo This should be a method core linking calls with a list of the
81
  /// UndefinedAtoms so that different drivers can format the error message
82
  /// as needed.
83
82
  bool printRemainingUndefines() const { return _printRemainingUndefines; }
84
85
  /// Normally, every UndefinedAtom must be replaced by a DefinedAtom or a
86
  /// SharedLibraryAtom for the link to be successful.  This method controls
87
  /// whether core linking considers remaining undefines to be an error.
88
31
  bool allowRemainingUndefines() const { return _allowRemainingUndefines; }
89
90
  /// Normally, every UndefinedAtom must be replaced by a DefinedAtom or a
91
  /// SharedLibraryAtom for the link to be successful.  This method controls
92
  /// whether core linking considers remaining undefines from the shared library
93
  /// to be an error.
94
0
  bool allowShlibUndefines() const { return _allowShlibUndefines; }
95
96
  /// If true, core linking will write the path to each input file to stdout
97
  /// (i.e. llvm::outs()) as it is used.  This is used to implement the -t
98
  /// linker option.
99
  ///
100
  /// \todo This should be a method core linking calls so that drivers can
101
  /// format the line as needed.
102
596
  bool logInputFiles() const { return _logInputFiles; }
103
104
  /// Parts of LLVM use global variables which are bound to command line
105
  /// options (see llvm::cl::Options). This method returns "command line"
106
  /// options which are used to configure LLVM's command line settings.
107
  /// For instance the -debug-only XXX option can be used to dynamically
108
  /// trace different parts of LLVM and lld.
109
225
  const std::vector<const char *> &llvmOptions() const { return _llvmOptions; }
110
111
  /// \name Methods used by Drivers to configure TargetInfo
112
  /// @{
113
241
  void setOutputPath(StringRef str) { _outputPath = str; }
114
115
  // Set the entry symbol name. You may also need to call addDeadStripRoot() for
116
  // the symbol if your platform supports dead-stripping, so that the symbol
117
  // will not be removed from the output.
118
5
  void setEntrySymbolName(StringRef name) {
119
5
    _entrySymbolName = name;
120
5
  }
121
122
14
  void setDeadStripping(bool enable) { _deadStrip = enable; }
123
143
  void setGlobalsAreDeadStripRoots(bool v) { _globalsAreDeadStripRoots = v; }
124
125
0
  void setPrintRemainingUndefines(bool print) {
126
0
    _printRemainingUndefines = print;
127
0
  }
128
129
0
  void setAllowRemainingUndefines(bool allow) {
130
0
    _allowRemainingUndefines = allow;
131
0
  }
132
133
0
  void setAllowShlibUndefines(bool allow) { _allowShlibUndefines = allow; }
134
1
  void setLogInputFiles(bool log) { _logInputFiles = log; }
135
136
0
  void appendLLVMOption(const char *opt) { _llvmOptions.push_back(opt); }
137
138
3.40k
  std::vector<std::unique_ptr<Node>> &getNodes() { return _nodes; }
139
0
  const std::vector<std::unique_ptr<Node>> &getNodes() const { return _nodes; }
140
141
  /// This method adds undefined symbols specified by the -u option to the to
142
  /// the list of undefined symbols known to the linker. This option essentially
143
  /// forces an undefined symbol to be created. You may also need to call
144
  /// addDeadStripRoot() for the symbol if your platform supports dead
145
  /// stripping, so that the symbol will not be removed from the output.
146
12
  void addInitialUndefinedSymbol(StringRef symbolName) {
147
12
    _initialUndefinedSymbols.push_back(symbolName);
148
12
  }
149
150
  /// Iterators for symbols that appear on the command line.
151
  typedef std::vector<StringRef> StringRefVector;
152
  typedef StringRefVector::iterator StringRefVectorIter;
153
  typedef StringRefVector::const_iterator StringRefVectorConstIter;
154
155
  /// Create linker internal files containing atoms for the linker to include
156
  /// during link. Flavors can override this function in their LinkingContext
157
  /// to add more internal files. These internal files are positioned before
158
  /// the actual input files.
159
  virtual void createInternalFiles(std::vector<std::unique_ptr<File>> &) const;
160
161
  /// Return the list of undefined symbols that are specified in the
162
  /// linker command line, using the -u option.
163
0
  ArrayRef<StringRef> initialUndefinedSymbols() const {
164
0
    return _initialUndefinedSymbols;
165
0
  }
166
167
  /// After all set* methods are called, the Driver calls this method
168
  /// to validate that there are no missing options or invalid combinations
169
  /// of options.  If there is a problem, a description of the problem
170
  /// is written to the supplied stream.
171
  ///
172
  /// \returns true if there is an error with the current settings.
173
  bool validate(raw_ostream &diagnostics);
174
175
  /// Formats symbol name for use in error messages.
176
  virtual std::string demangle(StringRef symbolName) const = 0;
177
178
  /// @}
179
  /// \name Methods used by Driver::link()
180
  /// @{
181
182
  /// Returns the file system path to which the linked output should be written.
183
  ///
184
  /// \todo To support in-memory linking, we need an abstraction that allows
185
  /// the linker to write to an in-memory buffer.
186
457
  StringRef outputPath() const { return _outputPath; }
187
188
  /// Accessor for Register object embedded in LinkingContext.
189
228
  const Registry &registry() const { return _registry; }
190
985
  Registry &registry() { return _registry; }
191
192
  /// This method is called by core linking to give the Writer a chance
193
  /// to add file format specific "files" to set of files to be linked. This is
194
  /// how file format specific atoms can be added to the link.
195
  virtual void createImplicitFiles(std::vector<std::unique_ptr<File>> &) = 0;
196
197
  /// This method is called by core linking to build the list of Passes to be
198
  /// run on the merged/linked graph of all input files.
199
  virtual void addPasses(PassManager &pm) = 0;
200
201
  /// Calls through to the writeFile() method on the specified Writer.
202
  ///
203
  /// \param linkedFile This is the merged/linked graph of all input file Atoms.
204
  virtual llvm::Error writeFile(const File &linkedFile) const;
205
206
  /// Return the next ordinal and Increment it.
207
1.00k
  virtual uint64_t getNextOrdinalAndIncrement() const { return _nextOrdinal++; }
208
209
  // This function is called just before the Resolver kicks in.
210
  // Derived classes may use it to change the list of input files.
211
  virtual void finalizeInputFiles() = 0;
212
213
  /// Callback invoked for each file the Resolver decides we are going to load.
214
  /// This can be used to update context state based on the file, and emit
215
  /// errors for any differences between the context state and a loaded file.
216
  /// For example, we can error if we try to load a file which is a different
217
  /// arch from that being linked.
218
  virtual llvm::Error handleLoadedFile(File &file) = 0;
219
220
  /// @}
221
protected:
222
  LinkingContext(); // Must be subclassed
223
224
  /// Abstract method to lazily instantiate the Writer.
225
  virtual Writer &writer() const = 0;
226
227
  /// Method to create an internal file for the entry symbol
228
  virtual std::unique_ptr<File> createEntrySymbolFile() const;
229
  std::unique_ptr<File> createEntrySymbolFile(StringRef filename) const;
230
231
  /// Method to create an internal file for an undefined symbol
232
  virtual std::unique_ptr<File> createUndefinedSymbolFile() const;
233
  std::unique_ptr<File> createUndefinedSymbolFile(StringRef filename) const;
234
235
  StringRef _outputPath;
236
  StringRef _entrySymbolName;
237
  bool _deadStrip = false;
238
  bool _globalsAreDeadStripRoots = false;
239
  bool _printRemainingUndefines = true;
240
  bool _allowRemainingUndefines = false;
241
  bool _logInputFiles = false;
242
  bool _allowShlibUndefines = false;
243
  std::vector<StringRef> _deadStripRoots;
244
  std::vector<const char *> _llvmOptions;
245
  StringRefVector _initialUndefinedSymbols;
246
  std::vector<std::unique_ptr<Node>> _nodes;
247
  mutable llvm::BumpPtrAllocator _allocator;
248
  mutable uint64_t _nextOrdinal = 0;
249
  Registry _registry;
250
251
private:
252
  /// Validate the subclass bits. Only called by validate.
253
  virtual bool validateImpl(raw_ostream &diagnostics) = 0;
254
};
255
256
} // end namespace lld
257
258
#endif // LLD_CORE_LINKING_CONTEXT_H