10b57cec5SDimitry Andric //===- Driver.h -------------------------------------------------*- C++ -*-===// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric 90b57cec5SDimitry Andric #ifndef LLD_COFF_DRIVER_H 100b57cec5SDimitry Andric #define LLD_COFF_DRIVER_H 110b57cec5SDimitry Andric 120b57cec5SDimitry Andric #include "Config.h" 130b57cec5SDimitry Andric #include "SymbolTable.h" 140b57cec5SDimitry Andric #include "lld/Common/LLVM.h" 150b57cec5SDimitry Andric #include "lld/Common/Reproduce.h" 160b57cec5SDimitry Andric #include "llvm/ADT/StringRef.h" 170b57cec5SDimitry Andric #include "llvm/ADT/StringSet.h" 180b57cec5SDimitry Andric #include "llvm/Object/Archive.h" 190b57cec5SDimitry Andric #include "llvm/Object/COFF.h" 200b57cec5SDimitry Andric #include "llvm/Option/Arg.h" 210b57cec5SDimitry Andric #include "llvm/Option/ArgList.h" 220b57cec5SDimitry Andric #include "llvm/Support/FileSystem.h" 230b57cec5SDimitry Andric #include "llvm/Support/TarWriter.h" 2481ad6265SDimitry Andric #include "llvm/WindowsDriver/MSVCPaths.h" 250b57cec5SDimitry Andric #include <memory> 26bdd1243dSDimitry Andric #include <optional> 270b57cec5SDimitry Andric #include <set> 280b57cec5SDimitry Andric #include <vector> 290b57cec5SDimitry Andric 30bdd1243dSDimitry Andric namespace lld::coff { 310b57cec5SDimitry Andric 320b57cec5SDimitry Andric using llvm::COFF::MachineTypes; 330b57cec5SDimitry Andric using llvm::COFF::WindowsSubsystem; 34bdd1243dSDimitry Andric using std::optional; 350b57cec5SDimitry Andric 36bdd1243dSDimitry Andric class COFFOptTable : public llvm::opt::GenericOptTable { 370b57cec5SDimitry Andric public: 380b57cec5SDimitry Andric COFFOptTable(); 390b57cec5SDimitry Andric }; 400b57cec5SDimitry Andric 415ffd83dbSDimitry Andric // The result of parsing the .drective section. The /export: and /include: 425ffd83dbSDimitry Andric // options are handled separately because they reference symbols, and the number 435ffd83dbSDimitry Andric // of symbols can be quite large. The LLVM Option library will perform at least 445ffd83dbSDimitry Andric // one memory allocation per argument, and that is prohibitively slow for 455ffd83dbSDimitry Andric // parsing directives. 465ffd83dbSDimitry Andric struct ParsedDirectives { 475ffd83dbSDimitry Andric std::vector<StringRef> exports; 485ffd83dbSDimitry Andric std::vector<StringRef> includes; 4961cfbce3SDimitry Andric std::vector<StringRef> excludes; 505ffd83dbSDimitry Andric llvm::opt::InputArgList args; 515ffd83dbSDimitry Andric }; 525ffd83dbSDimitry Andric 530b57cec5SDimitry Andric class ArgParser { 540b57cec5SDimitry Andric public: 55bdd1243dSDimitry Andric ArgParser(COFFLinkerContext &ctx); 56bdd1243dSDimitry Andric 5785868e8aSDimitry Andric // Parses command line options. 5885868e8aSDimitry Andric llvm::opt::InputArgList parse(llvm::ArrayRef<const char *> args); 590b57cec5SDimitry Andric 600b57cec5SDimitry Andric // Tokenizes a given string and then parses as command line options. 610b57cec5SDimitry Andric llvm::opt::InputArgList parse(StringRef s) { return parse(tokenize(s)); } 620b57cec5SDimitry Andric 630b57cec5SDimitry Andric // Tokenizes a given string and then parses as command line options in 640b57cec5SDimitry Andric // .drectve section. /EXPORT options are returned in second element 650b57cec5SDimitry Andric // to be processed in fastpath. 665ffd83dbSDimitry Andric ParsedDirectives parseDirectives(StringRef s); 670b57cec5SDimitry Andric 680b57cec5SDimitry Andric private: 6985868e8aSDimitry Andric // Concatenate LINK environment variable. 7085868e8aSDimitry Andric void addLINK(SmallVector<const char *, 256> &argv); 710b57cec5SDimitry Andric 720b57cec5SDimitry Andric std::vector<const char *> tokenize(StringRef s); 73bdd1243dSDimitry Andric 74bdd1243dSDimitry Andric COFFLinkerContext &ctx; 750b57cec5SDimitry Andric }; 760b57cec5SDimitry Andric 770b57cec5SDimitry Andric class LinkerDriver { 780b57cec5SDimitry Andric public: 79bdd1243dSDimitry Andric LinkerDriver(COFFLinkerContext &ctx) : ctx(ctx) {} 80349cc55cSDimitry Andric 81e8d8bef9SDimitry Andric void linkerMain(llvm::ArrayRef<const char *> args); 820b57cec5SDimitry Andric 8381ad6265SDimitry Andric // Adds various search paths based on the sysroot. Must only be called once 8481ad6265SDimitry Andric // config->machine has been set. 8581ad6265SDimitry Andric void addWinSysRootLibSearchPaths(); 8681ad6265SDimitry Andric 8706c3fb27SDimitry Andric void addClangLibSearchPaths(const std::string &argv0); 8806c3fb27SDimitry Andric 890b57cec5SDimitry Andric // Used by the resolver to parse .drectve section contents. 900b57cec5SDimitry Andric void parseDirectives(InputFile *file); 910b57cec5SDimitry Andric 920b57cec5SDimitry Andric // Used by ArchiveFile to enqueue members. 930b57cec5SDimitry Andric void enqueueArchiveMember(const Archive::Child &c, const Archive::Symbol &sym, 940b57cec5SDimitry Andric StringRef parentName); 950b57cec5SDimitry Andric 965ffd83dbSDimitry Andric void enqueuePDB(StringRef Path) { enqueuePath(Path, false, false); } 975ffd83dbSDimitry Andric 980b57cec5SDimitry Andric MemoryBufferRef takeBuffer(std::unique_ptr<MemoryBuffer> mb); 990b57cec5SDimitry Andric 10085868e8aSDimitry Andric void enqueuePath(StringRef path, bool wholeArchive, bool lazy); 1010b57cec5SDimitry Andric 1020b57cec5SDimitry Andric std::unique_ptr<llvm::TarWriter> tar; // for /linkrepro 1030b57cec5SDimitry Andric 104fe6060f1SDimitry Andric private: 1050b57cec5SDimitry Andric // Searches a file from search paths. 10606c3fb27SDimitry Andric std::optional<StringRef> findFileIfNew(StringRef filename); 10706c3fb27SDimitry Andric std::optional<StringRef> findLibIfNew(StringRef filename); 10806c3fb27SDimitry Andric StringRef findFile(StringRef filename); 10906c3fb27SDimitry Andric StringRef findLib(StringRef filename); 11006c3fb27SDimitry Andric StringRef findLibMinGW(StringRef filename); 1110b57cec5SDimitry Andric 112349cc55cSDimitry Andric bool findUnderscoreMangle(StringRef sym); 113349cc55cSDimitry Andric 11481ad6265SDimitry Andric // Determines the location of the sysroot based on `args`, environment, etc. 11581ad6265SDimitry Andric void detectWinSysRoot(const llvm::opt::InputArgList &args); 11681ad6265SDimitry Andric 117bdd1243dSDimitry Andric // Symbol names are mangled by prepending "_" on x86. 118bdd1243dSDimitry Andric StringRef mangle(StringRef sym); 119bdd1243dSDimitry Andric 120bdd1243dSDimitry Andric llvm::Triple::ArchType getArch(); 121bdd1243dSDimitry Andric 122bdd1243dSDimitry Andric uint64_t getDefaultImageBase(); 123bdd1243dSDimitry Andric 124bdd1243dSDimitry Andric bool isDecorated(StringRef sym); 125bdd1243dSDimitry Andric 126bdd1243dSDimitry Andric std::string getMapFile(const llvm::opt::InputArgList &args, 127bdd1243dSDimitry Andric llvm::opt::OptSpecifier os, 128bdd1243dSDimitry Andric llvm::opt::OptSpecifier osFile); 129bdd1243dSDimitry Andric 130bdd1243dSDimitry Andric std::string getImplibPath(); 131bdd1243dSDimitry Andric 132bdd1243dSDimitry Andric // The import name is calculated as follows: 133bdd1243dSDimitry Andric // 134bdd1243dSDimitry Andric // | LIBRARY w/ ext | LIBRARY w/o ext | no LIBRARY 135bdd1243dSDimitry Andric // -----+----------------+---------------------+------------------ 136bdd1243dSDimitry Andric // LINK | {value} | {value}.{.dll/.exe} | {output name} 137bdd1243dSDimitry Andric // LIB | {value} | {value}.dll | {output name}.dll 138bdd1243dSDimitry Andric // 139bdd1243dSDimitry Andric std::string getImportName(bool asLib); 140bdd1243dSDimitry Andric 141bdd1243dSDimitry Andric void createImportLibrary(bool asLib); 142bdd1243dSDimitry Andric 143bdd1243dSDimitry Andric void parseModuleDefs(StringRef path); 144bdd1243dSDimitry Andric 145bdd1243dSDimitry Andric // Parse an /order file. If an option is given, the linker places COMDAT 146bdd1243dSDimitry Andric // sections int he same order as their names appear in the given file. 147bdd1243dSDimitry Andric void parseOrderFile(StringRef arg); 148bdd1243dSDimitry Andric 149bdd1243dSDimitry Andric void parseCallGraphFile(StringRef path); 150bdd1243dSDimitry Andric 151bdd1243dSDimitry Andric void parsePDBAltPath(); 152bdd1243dSDimitry Andric 1530b57cec5SDimitry Andric // Parses LIB environment which contains a list of search paths. 1540b57cec5SDimitry Andric void addLibSearchPaths(); 1550b57cec5SDimitry Andric 1560b57cec5SDimitry Andric // Library search path. The first element is always "" (current directory). 1570b57cec5SDimitry Andric std::vector<StringRef> searchPaths; 1580b57cec5SDimitry Andric 15985868e8aSDimitry Andric // Convert resource files and potentially merge input resource object 16085868e8aSDimitry Andric // trees into one resource tree. 16185868e8aSDimitry Andric void convertResources(); 16285868e8aSDimitry Andric 1630b57cec5SDimitry Andric void maybeExportMinGWSymbols(const llvm::opt::InputArgList &args); 1640b57cec5SDimitry Andric 1650b57cec5SDimitry Andric // We don't want to add the same file more than once. 1660b57cec5SDimitry Andric // Files are uniquified by their filesystem and file number. 1670b57cec5SDimitry Andric std::set<llvm::sys::fs::UniqueID> visitedFiles; 1680b57cec5SDimitry Andric 1690b57cec5SDimitry Andric std::set<std::string> visitedLibs; 1700b57cec5SDimitry Andric 1710b57cec5SDimitry Andric Symbol *addUndefined(StringRef sym); 1720b57cec5SDimitry Andric 1730b57cec5SDimitry Andric StringRef mangleMaybe(Symbol *s); 1740b57cec5SDimitry Andric 1750b57cec5SDimitry Andric // Windows specific -- "main" is not the only main function in Windows. 1760b57cec5SDimitry Andric // You can choose one from these four -- {w,}{WinMain,main}. 1770b57cec5SDimitry Andric // There are four different entry point functions for them, 1780b57cec5SDimitry Andric // {w,}{WinMain,main}CRTStartup, respectively. The linker needs to 1790b57cec5SDimitry Andric // choose the right one depending on which "main" function is defined. 1800b57cec5SDimitry Andric // This function looks up the symbol table and resolve corresponding 1810b57cec5SDimitry Andric // entry point name. 1820b57cec5SDimitry Andric StringRef findDefaultEntry(); 1830b57cec5SDimitry Andric WindowsSubsystem inferSubsystem(); 1840b57cec5SDimitry Andric 18585868e8aSDimitry Andric void addBuffer(std::unique_ptr<MemoryBuffer> mb, bool wholeArchive, 18685868e8aSDimitry Andric bool lazy); 1870b57cec5SDimitry Andric void addArchiveBuffer(MemoryBufferRef mbref, StringRef symName, 1880b57cec5SDimitry Andric StringRef parentName, uint64_t offsetInArchive); 1890b57cec5SDimitry Andric 1900b57cec5SDimitry Andric void enqueueTask(std::function<void()> task); 1910b57cec5SDimitry Andric bool run(); 1920b57cec5SDimitry Andric 1930b57cec5SDimitry Andric std::list<std::function<void()>> taskQueue; 1940b57cec5SDimitry Andric std::vector<StringRef> filePaths; 1950b57cec5SDimitry Andric std::vector<MemoryBufferRef> resources; 1960b57cec5SDimitry Andric 19761cfbce3SDimitry Andric llvm::DenseSet<StringRef> directivesExports; 19861cfbce3SDimitry Andric llvm::DenseSet<StringRef> excludedSymbols; 199349cc55cSDimitry Andric 200349cc55cSDimitry Andric COFFLinkerContext &ctx; 20181ad6265SDimitry Andric 20281ad6265SDimitry Andric llvm::ToolsetLayout vsLayout = llvm::ToolsetLayout::OlderVS; 20381ad6265SDimitry Andric std::string vcToolChainPath; 20481ad6265SDimitry Andric llvm::SmallString<128> diaPath; 20581ad6265SDimitry Andric bool useWinSysRootLibPath = false; 20681ad6265SDimitry Andric llvm::SmallString<128> universalCRTLibPath; 20781ad6265SDimitry Andric int sdkMajor = 0; 20881ad6265SDimitry Andric llvm::SmallString<128> windowsSdkLibPath; 2090b57cec5SDimitry Andric 2100b57cec5SDimitry Andric // Functions below this line are defined in DriverUtils.cpp. 2110b57cec5SDimitry Andric 2120b57cec5SDimitry Andric void printHelp(const char *argv0); 2130b57cec5SDimitry Andric 2140b57cec5SDimitry Andric // Parses a string in the form of "<integer>[,<integer>]". 2150b57cec5SDimitry Andric void parseNumbers(StringRef arg, uint64_t *addr, uint64_t *size = nullptr); 2160b57cec5SDimitry Andric 2170b57cec5SDimitry Andric void parseGuard(StringRef arg); 2180b57cec5SDimitry Andric 2190b57cec5SDimitry Andric // Parses a string in the form of "<integer>[.<integer>]". 2200b57cec5SDimitry Andric // Minor's default value is 0. 2210b57cec5SDimitry Andric void parseVersion(StringRef arg, uint32_t *major, uint32_t *minor); 2220b57cec5SDimitry Andric 2230b57cec5SDimitry Andric // Parses a string in the form of "<subsystem>[,<integer>[.<integer>]]". 2240b57cec5SDimitry Andric void parseSubsystem(StringRef arg, WindowsSubsystem *sys, uint32_t *major, 225e8d8bef9SDimitry Andric uint32_t *minor, bool *gotVersion = nullptr); 2260b57cec5SDimitry Andric 2270b57cec5SDimitry Andric void parseAlternateName(StringRef); 2280b57cec5SDimitry Andric void parseMerge(StringRef); 229349cc55cSDimitry Andric void parsePDBPageSize(StringRef); 2300b57cec5SDimitry Andric void parseSection(StringRef); 2310b57cec5SDimitry Andric void parseAligncomm(StringRef); 2320b57cec5SDimitry Andric 2330b57cec5SDimitry Andric // Parses a string in the form of "[:<integer>]" 234bdd1243dSDimitry Andric void parseFunctionPadMin(llvm::opt::Arg *a); 2350b57cec5SDimitry Andric 236*5f757f3fSDimitry Andric // Parses a string in the form of "[:<integer>]" 237*5f757f3fSDimitry Andric void parseDependentLoadFlags(llvm::opt::Arg *a); 238*5f757f3fSDimitry Andric 2390b57cec5SDimitry Andric // Parses a string in the form of "EMBED[,=<integer>]|NO". 2400b57cec5SDimitry Andric void parseManifest(StringRef arg); 2410b57cec5SDimitry Andric 2420b57cec5SDimitry Andric // Parses a string in the form of "level=<string>|uiAccess=<string>" 2430b57cec5SDimitry Andric void parseManifestUAC(StringRef arg); 2440b57cec5SDimitry Andric 2450b57cec5SDimitry Andric // Parses a string in the form of "cd|net[,(cd|net)]*" 2460b57cec5SDimitry Andric void parseSwaprun(StringRef arg); 2470b57cec5SDimitry Andric 2480b57cec5SDimitry Andric // Create a resource file containing a manifest XML. 2490b57cec5SDimitry Andric std::unique_ptr<MemoryBuffer> createManifestRes(); 2500b57cec5SDimitry Andric void createSideBySideManifest(); 251bdd1243dSDimitry Andric std::string createDefaultXml(); 252bdd1243dSDimitry Andric std::string createManifestXmlWithInternalMt(StringRef defaultXml); 253bdd1243dSDimitry Andric std::string createManifestXmlWithExternalMt(StringRef defaultXml); 254bdd1243dSDimitry Andric std::string createManifestXml(); 255bdd1243dSDimitry Andric 256bdd1243dSDimitry Andric std::unique_ptr<llvm::WritableMemoryBuffer> 257bdd1243dSDimitry Andric createMemoryBufferForManifestRes(size_t manifestRes); 2580b57cec5SDimitry Andric 2590b57cec5SDimitry Andric // Used for dllexported symbols. 2600b57cec5SDimitry Andric Export parseExport(StringRef arg); 2610b57cec5SDimitry Andric void fixupExports(); 2620b57cec5SDimitry Andric void assignExportOrdinals(); 2630b57cec5SDimitry Andric 2640b57cec5SDimitry Andric // Parses a string in the form of "key=value" and check 2650b57cec5SDimitry Andric // if value matches previous values for the key. 2660b57cec5SDimitry Andric // This feature used in the directive section to reject 2670b57cec5SDimitry Andric // incompatible objects. 2680b57cec5SDimitry Andric void checkFailIfMismatch(StringRef arg, InputFile *source); 2690b57cec5SDimitry Andric 2700b57cec5SDimitry Andric // Convert Windows resource files (.res files) to a .obj file. 27185868e8aSDimitry Andric MemoryBufferRef convertResToCOFF(ArrayRef<MemoryBufferRef> mbs, 27285868e8aSDimitry Andric ArrayRef<ObjFile *> objs); 273bdd1243dSDimitry Andric }; 2740b57cec5SDimitry Andric 2750b57cec5SDimitry Andric // Create enum with OPT_xxx values for each option in Options.td 2760b57cec5SDimitry Andric enum { 2770b57cec5SDimitry Andric OPT_INVALID = 0, 278*5f757f3fSDimitry Andric #define OPTION(...) LLVM_MAKE_OPT_ID(__VA_ARGS__), 2790b57cec5SDimitry Andric #include "Options.inc" 2800b57cec5SDimitry Andric #undef OPTION 2810b57cec5SDimitry Andric }; 2820b57cec5SDimitry Andric 283bdd1243dSDimitry Andric } // namespace lld::coff 2840b57cec5SDimitry Andric 2850b57cec5SDimitry Andric #endif 286