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