Coverage Report

Created: 2018-08-19 14:04

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