LinkingContext.h revision 280461
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/Parallel.h"
17#include "lld/Core/Reference.h"
18#include "lld/Core/range.h"
19#include "lld/Core/Reader.h"
20#include "llvm/Support/ErrorOr.h"
21#include "llvm/Support/raw_ostream.h"
22#include <string>
23#include <vector>
24
25namespace lld {
26class PassManager;
27class File;
28class Writer;
29class Node;
30class SharedLibraryFile;
31
32/// \brief The LinkingContext class encapsulates "what and how" to link.
33///
34/// The base class LinkingContext contains the options needed by core linking.
35/// Subclasses of LinkingContext have additional options needed by specific
36/// Writers. For example, ELFLinkingContext has methods that supplies
37/// options to the ELF Writer and ELF Passes.
38class LinkingContext {
39public:
40  /// \brief The types of output file that the linker creates.
41  enum class OutputFileType : uint8_t {
42    Default, // The default output type for this target
43    YAML,    // The output type is set to YAML
44    Native   // The output file format is Native (Atoms)
45  };
46
47  virtual ~LinkingContext();
48
49  /// \name Methods needed by core linking
50  /// @{
51
52  /// Name of symbol linker should use as "entry point" to program,
53  /// usually "main" or "start".
54  virtual StringRef entrySymbolName() const { return _entrySymbolName; }
55
56  /// Whether core linking should remove Atoms not reachable by following
57  /// References from the entry point Atom or from all global scope Atoms
58  /// if globalsAreDeadStripRoots() is true.
59  bool deadStrip() const { return _deadStrip; }
60
61  /// Only used if deadStrip() returns true.  Means all global scope Atoms
62  /// should be marked live (along with all Atoms they reference).  Usually
63  /// this method returns false for main executables, but true for dynamic
64  /// shared libraries.
65  bool globalsAreDeadStripRoots() const { return _globalsAreDeadStripRoots; };
66
67  /// Only used if deadStrip() returns true.  This method returns the names
68  /// of DefinedAtoms that should be marked live (along with all Atoms they
69  /// reference). Only Atoms with scope scopeLinkageUnit or scopeGlobal can
70  /// be kept live using this method.
71  const std::vector<StringRef> &deadStripRoots() const {
72    return _deadStripRoots;
73  }
74
75  /// Add the given symbol name to the dead strip root set. Only used if
76  /// deadStrip() returns true.
77  void addDeadStripRoot(StringRef symbolName) {
78    assert(!symbolName.empty() && "Empty symbol cannot be a dead strip root");
79    _deadStripRoots.push_back(symbolName);
80  }
81
82  /// Archive files (aka static libraries) are normally lazily loaded.  That is,
83  /// object files within an archive are only loaded and linked in, if the
84  /// object file contains a DefinedAtom which will replace an existing
85  /// UndefinedAtom.  If this method returns true, core linking will also look
86  /// for archive members to replace existing tentative definitions in addition
87  /// to replacing undefines. Note: a "tentative definition" (also called a
88  /// "common" symbols) is a C (but not C++) concept. They are modeled in lld
89  /// as a DefinedAtom with merge() of mergeAsTentative.
90  bool searchArchivesToOverrideTentativeDefinitions() const {
91    return _searchArchivesToOverrideTentativeDefinitions;
92  }
93
94  /// Normally core linking will turn a tentative definition into a real
95  /// definition if not replaced by a real DefinedAtom from some object file.
96  /// If this method returns true, core linking will search all supplied
97  /// dynamic shared libraries for symbol names that match remaining tentative
98  /// definitions.  If any are found, the corresponding tentative definition
99  /// atom is replaced with SharedLibraryAtom.
100  bool searchSharedLibrariesToOverrideTentativeDefinitions() const {
101    return _searchSharedLibrariesToOverrideTentativeDefinitions;
102  }
103
104  /// Normally, every UndefinedAtom must be replaced by a DefinedAtom or a
105  /// SharedLibraryAtom for the link to be successful.  This method controls
106  /// whether core linking prints out a list of remaining UndefinedAtoms.
107  ///
108  /// \todo This should be a method core linking calls with a list of the
109  /// UndefinedAtoms so that different drivers can format the error message
110  /// as needed.
111  bool printRemainingUndefines() const { return _printRemainingUndefines; }
112
113  /// Normally, every UndefinedAtom must be replaced by a DefinedAtom or a
114  /// SharedLibraryAtom for the link to be successful.  This method controls
115  /// whether core linking considers remaining undefines to be an error.
116  bool allowRemainingUndefines() const { return _allowRemainingUndefines; }
117
118  /// In the lld model, a SharedLibraryAtom is a proxy atom for something
119  /// that will be found in a dynamic shared library when the program runs.
120  /// A SharedLibraryAtom optionally contains the name of the shared library
121  /// in which to find the symbol name at runtime.  Core linking may merge
122  /// two SharedLibraryAtom with the same name.  If this method returns true,
123  /// when merging core linking will also verify that they both have the same
124  /// loadName() and if not print a warning.
125  ///
126  /// \todo This should be a method core linking calls so that drivers can
127  /// format the warning as needed.
128  bool warnIfCoalesableAtomsHaveDifferentLoadName() const {
129    return _warnIfCoalesableAtomsHaveDifferentLoadName;
130  }
131
132  /// In C/C++ you can mark a function's prototype with
133  /// __attribute__((weak_import)) or __attribute__((weak)) to say the function
134  /// may not be available at runtime and/or build time and in which case its
135  /// address will evaluate to NULL. In lld this is modeled using the
136  /// UndefinedAtom::canBeNull() method.  During core linking, UndefinedAtom
137  /// with the same name are automatically merged.  If this method returns
138  /// true, core link also verfies that the canBeNull() value for merged
139  /// UndefinedAtoms are the same and warns if not.
140  ///
141  /// \todo This should be a method core linking calls so that drivers can
142  /// format the warning as needed.
143  bool warnIfCoalesableAtomsHaveDifferentCanBeNull() const {
144    return _warnIfCoalesableAtomsHaveDifferentCanBeNull;
145  }
146
147  /// Normally, every UndefinedAtom must be replaced by a DefinedAtom or a
148  /// SharedLibraryAtom for the link to be successful.  This method controls
149  /// whether core linking considers remaining undefines from the shared library
150  /// to be an error.
151  bool allowShlibUndefines() const { return _allowShlibUndefines; }
152
153  /// If true, core linking will write the path to each input file to stdout
154  /// (i.e. llvm::outs()) as it is used.  This is used to implement the -t
155  /// linker option.
156  ///
157  /// \todo This should be a method core linking calls so that drivers can
158  /// format the line as needed.
159  bool logInputFiles() const { return _logInputFiles; }
160
161  /// Parts of LLVM use global variables which are bound to command line
162  /// options (see llvm::cl::Options). This method returns "command line"
163  /// options which are used to configure LLVM's command line settings.
164  /// For instance the -debug-only XXX option can be used to dynamically
165  /// trace different parts of LLVM and lld.
166  const std::vector<const char *> &llvmOptions() const { return _llvmOptions; }
167
168  /// \name Methods used by Drivers to configure TargetInfo
169  /// @{
170  void setOutputPath(StringRef str) { _outputPath = str; }
171
172  // Set the entry symbol name. You may also need to call addDeadStripRoot() for
173  // the symbol if your platform supports dead-stripping, so that the symbol
174  // will not be removed from the output.
175  void setEntrySymbolName(StringRef name) {
176    _entrySymbolName = name;
177  }
178
179  void setDeadStripping(bool enable) { _deadStrip = enable; }
180  void setAllowDuplicates(bool enable) { _allowDuplicates = enable; }
181  void setGlobalsAreDeadStripRoots(bool v) { _globalsAreDeadStripRoots = v; }
182  void setSearchArchivesToOverrideTentativeDefinitions(bool search) {
183    _searchArchivesToOverrideTentativeDefinitions = search;
184  }
185  void setSearchSharedLibrariesToOverrideTentativeDefinitions(bool search) {
186    _searchSharedLibrariesToOverrideTentativeDefinitions = search;
187  }
188  void setWarnIfCoalesableAtomsHaveDifferentCanBeNull(bool warn) {
189    _warnIfCoalesableAtomsHaveDifferentCanBeNull = warn;
190  }
191  void setWarnIfCoalesableAtomsHaveDifferentLoadName(bool warn) {
192    _warnIfCoalesableAtomsHaveDifferentLoadName = warn;
193  }
194  void setPrintRemainingUndefines(bool print) {
195    _printRemainingUndefines = print;
196  }
197  void setAllowRemainingUndefines(bool allow) {
198    _allowRemainingUndefines = allow;
199  }
200  void setAllowShlibUndefines(bool allow) { _allowShlibUndefines = allow; }
201  void setLogInputFiles(bool log) { _logInputFiles = log; }
202
203  // Returns true if multiple definitions should not be treated as a
204  // fatal error.
205  bool getAllowDuplicates() const { return _allowDuplicates; }
206
207  void appendLLVMOption(const char *opt) { _llvmOptions.push_back(opt); }
208
209  void addAlias(StringRef from, StringRef to) { _aliasSymbols[from] = to; }
210  const std::map<std::string, std::string> &getAliases() const {
211    return _aliasSymbols;
212  }
213
214  std::vector<std::unique_ptr<Node>> &getNodes() { return _nodes; }
215  const std::vector<std::unique_ptr<Node>> &getNodes() const { return _nodes; }
216
217  /// Notify the LinkingContext when the symbol table found a name collision.
218  /// The useNew parameter specifies which the symbol table plans to keep,
219  /// but that can be changed by the LinkingContext.  This is also an
220  /// opportunity for flavor specific processing.
221  virtual void notifySymbolTableCoalesce(const Atom *existingAtom,
222                                         const Atom *newAtom, bool &useNew) {}
223
224  /// This method adds undefined symbols specified by the -u option to the to
225  /// the list of undefined symbols known to the linker. This option essentially
226  /// forces an undefined symbol to be created. You may also need to call
227  /// addDeadStripRoot() for the symbol if your platform supports dead
228  /// stripping, so that the symbol will not be removed from the output.
229  void addInitialUndefinedSymbol(StringRef symbolName) {
230    _initialUndefinedSymbols.push_back(symbolName);
231  }
232
233  /// Iterators for symbols that appear on the command line.
234  typedef std::vector<StringRef> StringRefVector;
235  typedef StringRefVector::iterator StringRefVectorIter;
236  typedef StringRefVector::const_iterator StringRefVectorConstIter;
237
238  /// Create linker internal files containing atoms for the linker to include
239  /// during link. Flavors can override this function in their LinkingContext
240  /// to add more internal files. These internal files are positioned before
241  /// the actual input files.
242  virtual void createInternalFiles(std::vector<std::unique_ptr<File> > &) const;
243
244  /// Return the list of undefined symbols that are specified in the
245  /// linker command line, using the -u option.
246  range<const StringRef *> initialUndefinedSymbols() const {
247    return _initialUndefinedSymbols;
248  }
249
250  /// After all set* methods are called, the Driver calls this method
251  /// to validate that there are no missing options or invalid combinations
252  /// of options.  If there is a problem, a description of the problem
253  /// is written to the supplied stream.
254  ///
255  /// \returns true if there is an error with the current settings.
256  bool validate(raw_ostream &diagnostics);
257
258  /// Formats symbol name for use in error messages.
259  virtual std::string demangle(StringRef symbolName) const {
260    return symbolName;
261  }
262
263  /// @}
264  /// \name Methods used by Driver::link()
265  /// @{
266
267  /// Returns the file system path to which the linked output should be written.
268  ///
269  /// \todo To support in-memory linking, we need an abstraction that allows
270  /// the linker to write to an in-memory buffer.
271  StringRef outputPath() const { return _outputPath; }
272
273  /// Set the various output file types that the linker would
274  /// create
275  bool setOutputFileType(StringRef outputFileType) {
276    if (outputFileType.equals_lower("yaml"))
277      _outputFileType = OutputFileType::YAML;
278    else if (outputFileType.equals_lower("native"))
279      _outputFileType = OutputFileType::YAML;
280    else
281      return false;
282    return true;
283  }
284
285  /// Returns the output file type that that the linker needs to create.
286  OutputFileType outputFileType() const { return _outputFileType; }
287
288  /// Accessor for Register object embedded in LinkingContext.
289  const Registry &registry() const { return _registry; }
290  Registry &registry() { return _registry; }
291
292  /// This method is called by core linking to give the Writer a chance
293  /// to add file format specific "files" to set of files to be linked. This is
294  /// how file format specific atoms can be added to the link.
295  virtual bool createImplicitFiles(std::vector<std::unique_ptr<File> > &);
296
297  /// This method is called by core linking to build the list of Passes to be
298  /// run on the merged/linked graph of all input files.
299  virtual void addPasses(PassManager &pm);
300
301  /// Calls through to the writeFile() method on the specified Writer.
302  ///
303  /// \param linkedFile This is the merged/linked graph of all input file Atoms.
304  virtual std::error_code writeFile(const File &linkedFile) const;
305
306  /// Return the next ordinal and Increment it.
307  virtual uint64_t getNextOrdinalAndIncrement() const { return _nextOrdinal++; }
308
309  // This function is called just before the Resolver kicks in.
310  // Derived classes may use it to change the list of input files.
311  virtual void finalizeInputFiles() {}
312
313  TaskGroup &getTaskGroup() { return _taskGroup; }
314
315  /// @}
316protected:
317  LinkingContext(); // Must be subclassed
318
319  /// Abstract method to lazily instantiate the Writer.
320  virtual Writer &writer() const = 0;
321
322  /// Method to create an internal file for the entry symbol
323  virtual std::unique_ptr<File> createEntrySymbolFile() const;
324  std::unique_ptr<File> createEntrySymbolFile(StringRef filename) const;
325
326  /// Method to create an internal file for an undefined symbol
327  virtual std::unique_ptr<File> createUndefinedSymbolFile() const;
328  std::unique_ptr<File> createUndefinedSymbolFile(StringRef filename) const;
329
330  /// Method to create an internal file for alias symbols
331  std::unique_ptr<File> createAliasSymbolFile() const;
332
333  StringRef _outputPath;
334  StringRef _entrySymbolName;
335  bool _deadStrip;
336  bool _allowDuplicates;
337  bool _globalsAreDeadStripRoots;
338  bool _searchArchivesToOverrideTentativeDefinitions;
339  bool _searchSharedLibrariesToOverrideTentativeDefinitions;
340  bool _warnIfCoalesableAtomsHaveDifferentCanBeNull;
341  bool _warnIfCoalesableAtomsHaveDifferentLoadName;
342  bool _printRemainingUndefines;
343  bool _allowRemainingUndefines;
344  bool _logInputFiles;
345  bool _allowShlibUndefines;
346  OutputFileType _outputFileType;
347  std::vector<StringRef> _deadStripRoots;
348  std::map<std::string, std::string> _aliasSymbols;
349  std::vector<const char *> _llvmOptions;
350  StringRefVector _initialUndefinedSymbols;
351  std::vector<std::unique_ptr<Node>> _nodes;
352  mutable llvm::BumpPtrAllocator _allocator;
353  mutable uint64_t _nextOrdinal;
354  Registry _registry;
355
356private:
357  /// Validate the subclass bits. Only called by validate.
358  virtual bool validateImpl(raw_ostream &diagnostics) = 0;
359  TaskGroup _taskGroup;
360};
361
362} // end namespace lld
363
364#endif
365