LinkingContext.h revision 341825
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 25namespace lld { 26 27class PassManager; 28class File; 29class Writer; 30class Node; 31class 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. 38class LinkingContext { 39public: 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 ®istry() const { return _registry; } 189 Registry ®istry() { 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 /// @} 220protected: 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 250private: 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 258