1 //===- Driver.h -------------------------------------------------*- C++ -*-===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #ifndef LLD_COFF_DRIVER_H 10 #define LLD_COFF_DRIVER_H 11 12 #include "Config.h" 13 #include "SymbolTable.h" 14 #include "lld/Common/LLVM.h" 15 #include "lld/Common/Reproduce.h" 16 #include "llvm/ADT/StringRef.h" 17 #include "llvm/ADT/StringSet.h" 18 #include "llvm/Object/Archive.h" 19 #include "llvm/Object/COFF.h" 20 #include "llvm/Option/Arg.h" 21 #include "llvm/Option/ArgList.h" 22 #include "llvm/Support/FileSystem.h" 23 #include "llvm/Support/TarWriter.h" 24 #include "llvm/WindowsDriver/MSVCPaths.h" 25 #include <memory> 26 #include <optional> 27 #include <set> 28 #include <vector> 29 30 namespace lld::coff { 31 32 using llvm::COFF::MachineTypes; 33 using llvm::COFF::WindowsSubsystem; 34 using std::optional; 35 36 class COFFOptTable : public llvm::opt::GenericOptTable { 37 public: 38 COFFOptTable(); 39 }; 40 41 // The result of parsing the .drective section. The /export: and /include: 42 // options are handled separately because they reference symbols, and the number 43 // of symbols can be quite large. The LLVM Option library will perform at least 44 // one memory allocation per argument, and that is prohibitively slow for 45 // parsing directives. 46 struct ParsedDirectives { 47 std::vector<StringRef> exports; 48 std::vector<StringRef> includes; 49 std::vector<StringRef> excludes; 50 llvm::opt::InputArgList args; 51 }; 52 53 class ArgParser { 54 public: 55 ArgParser(COFFLinkerContext &ctx); 56 57 // Parses command line options. 58 llvm::opt::InputArgList parse(llvm::ArrayRef<const char *> args); 59 60 // Tokenizes a given string and then parses as command line options. 61 llvm::opt::InputArgList parse(StringRef s) { return parse(tokenize(s)); } 62 63 // Tokenizes a given string and then parses as command line options in 64 // .drectve section. /EXPORT options are returned in second element 65 // to be processed in fastpath. 66 ParsedDirectives parseDirectives(StringRef s); 67 68 private: 69 // Concatenate LINK environment variable. 70 void addLINK(SmallVector<const char *, 256> &argv); 71 72 std::vector<const char *> tokenize(StringRef s); 73 74 COFFLinkerContext &ctx; 75 }; 76 77 class LinkerDriver { 78 public: 79 LinkerDriver(COFFLinkerContext &ctx) : ctx(ctx) {} 80 81 void linkerMain(llvm::ArrayRef<const char *> args); 82 83 // Adds various search paths based on the sysroot. Must only be called once 84 // config->machine has been set. 85 void addWinSysRootLibSearchPaths(); 86 87 void addClangLibSearchPaths(const std::string &argv0); 88 89 // Used by the resolver to parse .drectve section contents. 90 void parseDirectives(InputFile *file); 91 92 // Used by ArchiveFile to enqueue members. 93 void enqueueArchiveMember(const Archive::Child &c, const Archive::Symbol &sym, 94 StringRef parentName); 95 96 void enqueuePDB(StringRef Path) { enqueuePath(Path, false, false); } 97 98 MemoryBufferRef takeBuffer(std::unique_ptr<MemoryBuffer> mb); 99 100 void enqueuePath(StringRef path, bool wholeArchive, bool lazy); 101 102 std::unique_ptr<llvm::TarWriter> tar; // for /linkrepro 103 104 private: 105 // Searches a file from search paths. 106 std::optional<StringRef> findFileIfNew(StringRef filename); 107 std::optional<StringRef> findLibIfNew(StringRef filename); 108 StringRef findFile(StringRef filename); 109 StringRef findLib(StringRef filename); 110 StringRef findLibMinGW(StringRef filename); 111 112 bool findUnderscoreMangle(StringRef sym); 113 114 // Determines the location of the sysroot based on `args`, environment, etc. 115 void detectWinSysRoot(const llvm::opt::InputArgList &args); 116 117 // Symbol names are mangled by prepending "_" on x86. 118 StringRef mangle(StringRef sym); 119 120 llvm::Triple::ArchType getArch(); 121 122 uint64_t getDefaultImageBase(); 123 124 bool isDecorated(StringRef sym); 125 126 std::string getMapFile(const llvm::opt::InputArgList &args, 127 llvm::opt::OptSpecifier os, 128 llvm::opt::OptSpecifier osFile); 129 130 std::string getImplibPath(); 131 132 // The import name is calculated as follows: 133 // 134 // | LIBRARY w/ ext | LIBRARY w/o ext | no LIBRARY 135 // -----+----------------+---------------------+------------------ 136 // LINK | {value} | {value}.{.dll/.exe} | {output name} 137 // LIB | {value} | {value}.dll | {output name}.dll 138 // 139 std::string getImportName(bool asLib); 140 141 void createImportLibrary(bool asLib); 142 143 void parseModuleDefs(StringRef path); 144 145 // Parse an /order file. If an option is given, the linker places COMDAT 146 // sections int he same order as their names appear in the given file. 147 void parseOrderFile(StringRef arg); 148 149 void parseCallGraphFile(StringRef path); 150 151 void parsePDBAltPath(); 152 153 // Parses LIB environment which contains a list of search paths. 154 void addLibSearchPaths(); 155 156 // Library search path. The first element is always "" (current directory). 157 std::vector<StringRef> searchPaths; 158 159 // Convert resource files and potentially merge input resource object 160 // trees into one resource tree. 161 void convertResources(); 162 163 void maybeExportMinGWSymbols(const llvm::opt::InputArgList &args); 164 165 // We don't want to add the same file more than once. 166 // Files are uniquified by their filesystem and file number. 167 std::set<llvm::sys::fs::UniqueID> visitedFiles; 168 169 std::set<std::string> visitedLibs; 170 171 Symbol *addUndefined(StringRef sym); 172 173 StringRef mangleMaybe(Symbol *s); 174 175 // Windows specific -- "main" is not the only main function in Windows. 176 // You can choose one from these four -- {w,}{WinMain,main}. 177 // There are four different entry point functions for them, 178 // {w,}{WinMain,main}CRTStartup, respectively. The linker needs to 179 // choose the right one depending on which "main" function is defined. 180 // This function looks up the symbol table and resolve corresponding 181 // entry point name. 182 StringRef findDefaultEntry(); 183 WindowsSubsystem inferSubsystem(); 184 185 void addBuffer(std::unique_ptr<MemoryBuffer> mb, bool wholeArchive, 186 bool lazy); 187 void addArchiveBuffer(MemoryBufferRef mbref, StringRef symName, 188 StringRef parentName, uint64_t offsetInArchive); 189 190 void enqueueTask(std::function<void()> task); 191 bool run(); 192 193 std::list<std::function<void()>> taskQueue; 194 std::vector<StringRef> filePaths; 195 std::vector<MemoryBufferRef> resources; 196 197 llvm::DenseSet<StringRef> directivesExports; 198 llvm::DenseSet<StringRef> excludedSymbols; 199 200 COFFLinkerContext &ctx; 201 202 llvm::ToolsetLayout vsLayout = llvm::ToolsetLayout::OlderVS; 203 std::string vcToolChainPath; 204 llvm::SmallString<128> diaPath; 205 bool useWinSysRootLibPath = false; 206 llvm::SmallString<128> universalCRTLibPath; 207 int sdkMajor = 0; 208 llvm::SmallString<128> windowsSdkLibPath; 209 210 // Functions below this line are defined in DriverUtils.cpp. 211 212 void printHelp(const char *argv0); 213 214 // Parses a string in the form of "<integer>[,<integer>]". 215 void parseNumbers(StringRef arg, uint64_t *addr, uint64_t *size = nullptr); 216 217 void parseGuard(StringRef arg); 218 219 // Parses a string in the form of "<integer>[.<integer>]". 220 // Minor's default value is 0. 221 void parseVersion(StringRef arg, uint32_t *major, uint32_t *minor); 222 223 // Parses a string in the form of "<subsystem>[,<integer>[.<integer>]]". 224 void parseSubsystem(StringRef arg, WindowsSubsystem *sys, uint32_t *major, 225 uint32_t *minor, bool *gotVersion = nullptr); 226 227 void parseAlternateName(StringRef); 228 void parseMerge(StringRef); 229 void parsePDBPageSize(StringRef); 230 void parseSection(StringRef); 231 void parseAligncomm(StringRef); 232 233 // Parses a string in the form of "[:<integer>]" 234 void parseFunctionPadMin(llvm::opt::Arg *a); 235 236 // Parses a string in the form of "EMBED[,=<integer>]|NO". 237 void parseManifest(StringRef arg); 238 239 // Parses a string in the form of "level=<string>|uiAccess=<string>" 240 void parseManifestUAC(StringRef arg); 241 242 // Parses a string in the form of "cd|net[,(cd|net)]*" 243 void parseSwaprun(StringRef arg); 244 245 // Create a resource file containing a manifest XML. 246 std::unique_ptr<MemoryBuffer> createManifestRes(); 247 void createSideBySideManifest(); 248 std::string createDefaultXml(); 249 std::string createManifestXmlWithInternalMt(StringRef defaultXml); 250 std::string createManifestXmlWithExternalMt(StringRef defaultXml); 251 std::string createManifestXml(); 252 253 std::unique_ptr<llvm::WritableMemoryBuffer> 254 createMemoryBufferForManifestRes(size_t manifestRes); 255 256 // Used for dllexported symbols. 257 Export parseExport(StringRef arg); 258 void fixupExports(); 259 void assignExportOrdinals(); 260 261 // Parses a string in the form of "key=value" and check 262 // if value matches previous values for the key. 263 // This feature used in the directive section to reject 264 // incompatible objects. 265 void checkFailIfMismatch(StringRef arg, InputFile *source); 266 267 // Convert Windows resource files (.res files) to a .obj file. 268 MemoryBufferRef convertResToCOFF(ArrayRef<MemoryBufferRef> mbs, 269 ArrayRef<ObjFile *> objs); 270 }; 271 272 // Create enum with OPT_xxx values for each option in Options.td 273 enum { 274 OPT_INVALID = 0, 275 #define OPTION(_1, _2, ID, _4, _5, _6, _7, _8, _9, _10, _11, _12) OPT_##ID, 276 #include "Options.inc" 277 #undef OPTION 278 }; 279 280 } // namespace lld::coff 281 282 #endif 283