xref: /freebsd/contrib/llvm-project/lld/COFF/Driver.h (revision 5f757f3ff9144b609b3c433dfd370cc6bdc191ad)
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