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 ®istry() const { return _registry; } 183 Registry ®istry() { 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