]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/tools/lld/include/lld/Core/LinkingContext.h
Merge clang 7.0.1 and several follow-up changes
[FreeBSD/FreeBSD.git] / contrib / llvm / tools / lld / include / lld / Core / LinkingContext.h
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   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   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   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   ArrayRef<StringRef> deadStripRoots() const {
65     return _deadStripRoots;
66   }
67
68   /// Add the given symbol name to the dead strip root set. Only used if
69   /// deadStrip() returns true.
70   void addDeadStripRoot(StringRef symbolName) {
71     assert(!symbolName.empty() && "Empty symbol cannot be a dead strip root");
72     _deadStripRoots.push_back(symbolName);
73   }
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   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   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   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   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   ArrayRef<const char *> llvmOptions() const { return _llvmOptions; }
109
110   /// \name Methods used by Drivers to configure TargetInfo
111   /// @{
112   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   void setEntrySymbolName(StringRef name) {
118     _entrySymbolName = name;
119   }
120
121   void setDeadStripping(bool enable) { _deadStrip = enable; }
122   void setGlobalsAreDeadStripRoots(bool v) { _globalsAreDeadStripRoots = v; }
123
124   void setPrintRemainingUndefines(bool print) {
125     _printRemainingUndefines = print;
126   }
127
128   void setAllowRemainingUndefines(bool allow) {
129     _allowRemainingUndefines = allow;
130   }
131
132   void setAllowShlibUndefines(bool allow) { _allowShlibUndefines = allow; }
133   void setLogInputFiles(bool log) { _logInputFiles = log; }
134
135   void appendLLVMOption(const char *opt) { _llvmOptions.push_back(opt); }
136
137   std::vector<std::unique_ptr<Node>> &getNodes() { return _nodes; }
138   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   void addInitialUndefinedSymbol(StringRef symbolName) {
146     _initialUndefinedSymbols.push_back(symbolName);
147   }
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   ArrayRef<StringRef> initialUndefinedSymbols() const {
163     return _initialUndefinedSymbols;
164   }
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   StringRef outputPath() const { return _outputPath; }
186
187   /// Accessor for Register object embedded in LinkingContext.
188   const Registry &registry() const { return _registry; }
189   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   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