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/Optional.h" |
17 | #include "llvm/ADT/StringRef.h" |
18 | #include "llvm/ADT/StringSet.h" |
19 | #include "llvm/Object/Archive.h" |
20 | #include "llvm/Object/COFF.h" |
21 | #include "llvm/Option/Arg.h" |
22 | #include "llvm/Option/ArgList.h" |
23 | #include "llvm/Support/FileSystem.h" |
24 | #include "llvm/Support/TarWriter.h" |
25 | #include <memory> |
26 | #include <set> |
27 | #include <vector> |
28 | |
29 | namespace lld { |
30 | namespace coff { |
31 | |
32 | class LinkerDriver; |
33 | extern LinkerDriver *driver; |
34 | |
35 | using llvm::COFF::MachineTypes; |
36 | using llvm::COFF::WindowsSubsystem; |
37 | using llvm::Optional; |
38 | |
39 | class COFFOptTable : public llvm::opt::OptTable { |
40 | public: |
41 | COFFOptTable(); |
42 | }; |
43 | |
44 | // Constructing the option table is expensive. Use a global table to avoid doing |
45 | // it more than once. |
46 | extern COFFOptTable optTable; |
47 | |
48 | // The result of parsing the .drective section. The /export: and /include: |
49 | // options are handled separately because they reference symbols, and the number |
50 | // of symbols can be quite large. The LLVM Option library will perform at least |
51 | // one memory allocation per argument, and that is prohibitively slow for |
52 | // parsing directives. |
53 | struct ParsedDirectives { |
54 | std::vector<StringRef> exports; |
55 | std::vector<StringRef> includes; |
56 | llvm::opt::InputArgList args; |
57 | }; |
58 | |
59 | class ArgParser { |
60 | public: |
61 | // Parses command line options. |
62 | llvm::opt::InputArgList parse(llvm::ArrayRef<const char *> args); |
63 | |
64 | // Tokenizes a given string and then parses as command line options. |
65 | llvm::opt::InputArgList parse(StringRef s) { return parse(tokenize(s)); } |
66 | |
67 | // Tokenizes a given string and then parses as command line options in |
68 | // .drectve section. /EXPORT options are returned in second element |
69 | // to be processed in fastpath. |
70 | ParsedDirectives parseDirectives(StringRef s); |
71 | |
72 | private: |
73 | // Concatenate LINK environment variable. |
74 | void addLINK(SmallVector<const char *, 256> &argv); |
75 | |
76 | std::vector<const char *> tokenize(StringRef s); |
77 | }; |
78 | |
79 | class LinkerDriver { |
80 | public: |
81 | void linkerMain(llvm::ArrayRef<const char *> args); |
82 | |
83 | // Used by the resolver to parse .drectve section contents. |
84 | void parseDirectives(InputFile *file); |
85 | |
86 | // Used by ArchiveFile to enqueue members. |
87 | void enqueueArchiveMember(const Archive::Child &c, const Archive::Symbol &sym, |
88 | StringRef parentName); |
89 | |
90 | void enqueuePDB(StringRef Path) { enqueuePath(Path, false, false); } |
91 | |
92 | MemoryBufferRef takeBuffer(std::unique_ptr<MemoryBuffer> mb); |
93 | |
94 | void enqueuePath(StringRef path, bool wholeArchive, bool lazy); |
95 | |
96 | std::unique_ptr<llvm::TarWriter> tar; // for /linkrepro |
97 | |
98 | private: |
99 | // Searches a file from search paths. |
100 | Optional<StringRef> findFile(StringRef filename); |
101 | Optional<StringRef> findLib(StringRef filename); |
102 | StringRef doFindFile(StringRef filename); |
103 | StringRef doFindLib(StringRef filename); |
104 | StringRef doFindLibMinGW(StringRef filename); |
105 | |
106 | // Parses LIB environment which contains a list of search paths. |
107 | void addLibSearchPaths(); |
108 | |
109 | // Library search path. The first element is always "" (current directory). |
110 | std::vector<StringRef> searchPaths; |
111 | |
112 | // Convert resource files and potentially merge input resource object |
113 | // trees into one resource tree. |
114 | void convertResources(); |
115 | |
116 | void maybeExportMinGWSymbols(const llvm::opt::InputArgList &args); |
117 | |
118 | // We don't want to add the same file more than once. |
119 | // Files are uniquified by their filesystem and file number. |
120 | std::set<llvm::sys::fs::UniqueID> visitedFiles; |
121 | |
122 | std::set<std::string> visitedLibs; |
123 | |
124 | Symbol *addUndefined(StringRef sym); |
125 | |
126 | StringRef mangleMaybe(Symbol *s); |
127 | |
128 | // Windows specific -- "main" is not the only main function in Windows. |
129 | // You can choose one from these four -- {w,}{WinMain,main}. |
130 | // There are four different entry point functions for them, |
131 | // {w,}{WinMain,main}CRTStartup, respectively. The linker needs to |
132 | // choose the right one depending on which "main" function is defined. |
133 | // This function looks up the symbol table and resolve corresponding |
134 | // entry point name. |
135 | StringRef findDefaultEntry(); |
136 | WindowsSubsystem inferSubsystem(); |
137 | |
138 | void addBuffer(std::unique_ptr<MemoryBuffer> mb, bool wholeArchive, |
139 | bool lazy); |
140 | void addArchiveBuffer(MemoryBufferRef mbref, StringRef symName, |
141 | StringRef parentName, uint64_t offsetInArchive); |
142 | |
143 | void enqueueTask(std::function<void()> task); |
144 | bool run(); |
145 | |
146 | std::list<std::function<void()>> taskQueue; |
147 | std::vector<StringRef> filePaths; |
148 | std::vector<MemoryBufferRef> resources; |
149 | |
150 | llvm::StringSet<> directivesExports; |
151 | }; |
152 | |
153 | // Functions below this line are defined in DriverUtils.cpp. |
154 | |
155 | void printHelp(const char *argv0); |
156 | |
157 | // Parses a string in the form of "<integer>[,<integer>]". |
158 | void parseNumbers(StringRef arg, uint64_t *addr, uint64_t *size = nullptr); |
159 | |
160 | void parseGuard(StringRef arg); |
161 | |
162 | // Parses a string in the form of "<integer>[.<integer>]". |
163 | // Minor's default value is 0. |
164 | void parseVersion(StringRef arg, uint32_t *major, uint32_t *minor); |
165 | |
166 | // Parses a string in the form of "<subsystem>[,<integer>[.<integer>]]". |
167 | void parseSubsystem(StringRef arg, WindowsSubsystem *sys, uint32_t *major, |
168 | uint32_t *minor, bool *gotVersion = nullptr); |
169 | |
170 | void parseAlternateName(StringRef); |
171 | void parseMerge(StringRef); |
172 | void parseSection(StringRef); |
173 | void parseAligncomm(StringRef); |
174 | |
175 | // Parses a string in the form of "[:<integer>]" |
176 | void parseFunctionPadMin(llvm::opt::Arg *a, llvm::COFF::MachineTypes machine); |
177 | |
178 | // Parses a string in the form of "EMBED[,=<integer>]|NO". |
179 | void parseManifest(StringRef arg); |
180 | |
181 | // Parses a string in the form of "level=<string>|uiAccess=<string>" |
182 | void parseManifestUAC(StringRef arg); |
183 | |
184 | // Parses a string in the form of "cd|net[,(cd|net)]*" |
185 | void parseSwaprun(StringRef arg); |
186 | |
187 | // Create a resource file containing a manifest XML. |
188 | std::unique_ptr<MemoryBuffer> createManifestRes(); |
189 | void createSideBySideManifest(); |
190 | |
191 | // Used for dllexported symbols. |
192 | Export parseExport(StringRef arg); |
193 | void fixupExports(); |
194 | void assignExportOrdinals(); |
195 | |
196 | // Parses a string in the form of "key=value" and check |
197 | // if value matches previous values for the key. |
198 | // This feature used in the directive section to reject |
199 | // incompatible objects. |
200 | void checkFailIfMismatch(StringRef arg, InputFile *source); |
201 | |
202 | // Convert Windows resource files (.res files) to a .obj file. |
203 | MemoryBufferRef convertResToCOFF(ArrayRef<MemoryBufferRef> mbs, |
204 | ArrayRef<ObjFile *> objs); |
205 | |
206 | // Create enum with OPT_xxx values for each option in Options.td |
207 | enum { |
208 | OPT_INVALID = 0, |
209 | #define OPTION(_1, _2, ID, _4, _5, _6, _7, _8, _9, _10, _11, _12) OPT_##ID, |
210 | #include "Options.inc" |
211 | #undef OPTION |
212 | }; |
213 | |
214 | } // namespace coff |
215 | } // namespace lld |
216 | |
217 | #endif |
218 | |