]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/tools/lld/include/lld/Core/LinkingContext.h
Bring lld (release_39 branch, r279477) to contrib
[FreeBSD/FreeBSD.git] / contrib / llvm / tools / lld / include / lld / Core / LinkingContext.h
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
23 namespace lld {
24 class PassManager;
25 class File;
26 class Writer;
27 class Node;
28 class 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.
35 class LinkingContext {
36 public:
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   /// @}
214 protected:
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
244 private:
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