1//===- Config.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_CONFIG_H
10#define LLD_COFF_CONFIG_H
11
12#include "lld/Common/ErrorHandler.h"
13#include "llvm/ADT/MapVector.h"
14#include "llvm/ADT/SetVector.h"
15#include "llvm/ADT/SmallVector.h"
16#include "llvm/ADT/StringMap.h"
17#include "llvm/ADT/StringRef.h"
18#include "llvm/Object/COFF.h"
19#include "llvm/Support/CachePruning.h"
20#include "llvm/Support/VirtualFileSystem.h"
21#include <cstdint>
22#include <map>
23#include <set>
24#include <string>
25
26namespace lld::coff {
27
28using llvm::COFF::IMAGE_FILE_MACHINE_UNKNOWN;
29using llvm::COFF::WindowsSubsystem;
30using llvm::StringRef;
31class COFFLinkerContext;
32class DefinedAbsolute;
33class StringChunk;
34class Symbol;
35class InputFile;
36class SectionChunk;
37
38// Short aliases.
39static const auto AMD64 = llvm::COFF::IMAGE_FILE_MACHINE_AMD64;
40static const auto ARM64 = llvm::COFF::IMAGE_FILE_MACHINE_ARM64;
41static const auto ARM64EC = llvm::COFF::IMAGE_FILE_MACHINE_ARM64EC;
42static const auto ARM64X = llvm::COFF::IMAGE_FILE_MACHINE_ARM64X;
43static const auto ARMNT = llvm::COFF::IMAGE_FILE_MACHINE_ARMNT;
44static const auto I386 = llvm::COFF::IMAGE_FILE_MACHINE_I386;
45
46enum class ExportSource {
47 Unset,
48 Directives,
49 Export,
50 ModuleDefinition,
51};
52
53enum class EmitKind { Obj, LLVM, ASM };
54
55// Represents an /export option.
56struct Export {
57 StringRef name; // N in /export:N or /export:E=N
58 StringRef extName; // E in /export:E=N
59 StringRef exportAs; // E in /export:N,EXPORTAS,E
60 StringRef importName; // GNU specific: N in "othername == N"
61 Symbol *sym = nullptr;
62 uint16_t ordinal = 0;
63 bool noname = false;
64 bool data = false;
65 bool isPrivate = false;
66 bool constant = false;
67
68 // If an export is a form of /export:foo=dllname.bar, that means
69 // that foo should be exported as an alias to bar in the DLL.
70 // forwardTo is set to "dllname.bar" part. Usually empty.
71 StringRef forwardTo;
72 StringChunk *forwardChunk = nullptr;
73
74 ExportSource source = ExportSource::Unset;
75 StringRef symbolName;
76 StringRef exportName; // Name in DLL
77
78 bool operator==(const Export &e) const {
79 return (name == e.name && extName == e.extName && exportAs == e.exportAs &&
80 importName == e.importName && ordinal == e.ordinal &&
81 noname == e.noname && data == e.data && isPrivate == e.isPrivate);
82 }
83};
84
85enum class DebugType {
86 None = 0x0,
87 CV = 0x1, /// CodeView
88 PData = 0x2, /// Procedure Data
89 Fixup = 0x4, /// Relocation Table
90};
91
92enum GuardCFLevel {
93 Off = 0x0,
94 CF = 0x1, /// Emit gfids tables
95 LongJmp = 0x2, /// Emit longjmp tables
96 EHCont = 0x4, /// Emit ehcont tables
97 All = 0x7 /// Enable all protections
98};
99
100enum class ICFLevel {
101 None,
102 Safe, // Safe ICF for all sections.
103 All, // Aggressive ICF for code, but safe ICF for data, similar to MSVC's
104 // behavior.
105};
106
107enum class BuildIDHash {
108 None,
109 PDB,
110 Binary,
111};
112
113// Global configuration.
114struct Configuration {
115 enum ManifestKind { Default, SideBySide, Embed, No };
116 bool is64() const { return llvm::COFF::is64Bit(Machine: machine); }
117
118 std::unique_ptr<MemoryBuffer> dosStub;
119 llvm::COFF::MachineTypes machine = IMAGE_FILE_MACHINE_UNKNOWN;
120 bool machineInferred = false;
121 size_t wordsize;
122 bool verbose = false;
123 WindowsSubsystem subsystem = llvm::COFF::IMAGE_SUBSYSTEM_UNKNOWN;
124 bool noEntry = false;
125 std::string outputFile;
126 std::string importName;
127 bool demangle = true;
128 bool doGC = true;
129 ICFLevel doICF = ICFLevel::None;
130 bool tailMerge;
131 bool relocatable = true;
132 bool forceMultiple = false;
133 bool forceMultipleRes = false;
134 bool forceUnresolved = false;
135 bool debug = false;
136 bool includeDwarfChunks = false;
137 bool debugGHashes = false;
138 bool writeSymtab = false;
139 bool driver = false;
140 bool driverUponly = false;
141 bool driverWdm = false;
142 bool showTiming = false;
143 bool showSummary = false;
144 bool printSearchPaths = false;
145 unsigned debugTypes = static_cast<unsigned>(DebugType::None);
146 llvm::SmallVector<llvm::StringRef, 0> mllvmOpts;
147 std::vector<std::string> natvisFiles;
148 llvm::StringMap<std::string> namedStreams;
149 llvm::SmallString<128> pdbAltPath;
150 int pdbPageSize = 4096;
151 llvm::SmallString<128> pdbPath;
152 llvm::SmallString<128> pdbSourcePath;
153 std::vector<llvm::StringRef> argv;
154
155 // Symbols in this set are considered as live by the garbage collector.
156 std::vector<Symbol *> gcroot;
157
158 std::set<std::string> noDefaultLibs;
159 bool noDefaultLibAll = false;
160
161 // True if we are creating a DLL.
162 bool dll = false;
163 StringRef implib;
164 bool noimplib = false;
165 std::set<std::string> delayLoads;
166 std::map<std::string, int> dllOrder;
167 Symbol *arm64ECIcallHelper = nullptr;
168
169 llvm::DenseSet<llvm::StringRef> saveTempsArgs;
170
171 // /guard:cf
172 int guardCF = GuardCFLevel::Off;
173
174 // Used for SafeSEH.
175 bool safeSEH = false;
176 Symbol *sehTable = nullptr;
177 Symbol *sehCount = nullptr;
178 bool noSEH = false;
179
180 // Used for /opt:lldlto=N
181 unsigned ltoo = 2;
182 // Used for /opt:lldltocgo=N
183 std::optional<unsigned> ltoCgo;
184
185 // Used for /opt:lldltojobs=N
186 std::string thinLTOJobs;
187 // Used for /opt:lldltopartitions=N
188 unsigned ltoPartitions = 1;
189
190 // Used for /lldltocache=path
191 StringRef ltoCache;
192 // Used for /lldltocachepolicy=policy
193 llvm::CachePruningPolicy ltoCachePolicy;
194
195 // Used for /thinlto-distributor:<path>
196 StringRef dtltoDistributor;
197
198 // Used for /thinlto-distributor-arg:<arg>
199 llvm::SmallVector<llvm::StringRef, 0> dtltoDistributorArgs;
200
201 // Used for /thinlto-remote-compiler:<path>
202 StringRef dtltoCompiler;
203
204 // Used for /thinlto-remote-compiler-arg:<arg>
205 llvm::SmallVector<llvm::StringRef, 0> dtltoCompilerArgs;
206
207 // Used for /opt:[no]ltodebugpassmanager
208 bool ltoDebugPassManager = false;
209
210 // Used for /merge:from=to (e.g. /merge:.rdata=.text)
211 std::map<StringRef, StringRef> merge;
212
213 // Used for /section=.name,{DEKPRSW} to set section attributes.
214 std::map<StringRef, uint32_t> section;
215
216 // Options for manifest files.
217 ManifestKind manifest = Default;
218 int manifestID = 1;
219 llvm::SetVector<StringRef> manifestDependencies;
220 bool manifestUAC = true;
221 std::vector<std::string> manifestInput;
222 StringRef manifestLevel = "'asInvoker'";
223 StringRef manifestUIAccess = "'false'";
224 StringRef manifestFile;
225
226 // used for /dwodir
227 StringRef dwoDir;
228
229 // Used for /failifmismatch.
230 std::map<StringRef, std::pair<StringRef, InputFile *>> mustMatch;
231
232 // Used for /order.
233 llvm::StringMap<int> order;
234
235 // Used for /lldmap.
236 std::string lldmapFile;
237
238 // Used for /map.
239 std::string mapFile;
240
241 // Used for /mapinfo.
242 bool mapInfo = false;
243
244 // Used for /thinlto-index-only:
245 llvm::StringRef thinLTOIndexOnlyArg;
246
247 // Used for /thinlto-prefix-replace:
248 // Replace the prefix in paths generated for ThinLTO, replacing
249 // thinLTOPrefixReplaceOld with thinLTOPrefixReplaceNew. If
250 // thinLTOPrefixReplaceNativeObject is defined, replace the prefix of object
251 // file paths written to the response file given in the
252 // --thinlto-index-only=${response} option with
253 // thinLTOPrefixReplaceNativeObject, instead of thinLTOPrefixReplaceNew.
254 llvm::StringRef thinLTOPrefixReplaceOld;
255 llvm::StringRef thinLTOPrefixReplaceNew;
256 llvm::StringRef thinLTOPrefixReplaceNativeObject;
257
258 // Used for /thinlto-object-suffix-replace:
259 std::pair<llvm::StringRef, llvm::StringRef> thinLTOObjectSuffixReplace;
260
261 // Used for /lto-obj-path:
262 llvm::StringRef ltoObjPath;
263
264 // Used for /lto-cs-profile-generate:
265 bool ltoCSProfileGenerate = false;
266
267 // Used for /lto-cs-profile-path
268 llvm::StringRef ltoCSProfileFile;
269
270 // Used for /lto-pgo-warn-mismatch:
271 bool ltoPGOWarnMismatch = true;
272
273 // Used for /lto-sample-profile:
274 llvm::StringRef ltoSampleProfileName;
275
276 // Used for /call-graph-ordering-file:
277 llvm::MapVector<std::pair<const SectionChunk *, const SectionChunk *>,
278 uint64_t>
279 callGraphProfile;
280 bool callGraphProfileSort = false;
281
282 // Used for /print-symbol-order:
283 StringRef printSymbolOrder;
284
285 // Used for /vfsoverlay:
286 std::unique_ptr<llvm::vfs::FileSystem> vfs;
287
288 uint64_t align = 4096;
289 uint64_t imageBase = -1;
290 uint64_t fileAlign = 512;
291 uint64_t stackReserve = 1024 * 1024;
292 uint64_t stackCommit = 4096;
293 uint64_t heapReserve = 1024 * 1024;
294 uint64_t heapCommit = 4096;
295 uint32_t majorImageVersion = 0;
296 uint32_t minorImageVersion = 0;
297 // If changing the default os/subsys version here, update the default in
298 // the MinGW driver accordingly.
299 uint32_t majorOSVersion = 6;
300 uint32_t minorOSVersion = 0;
301 uint32_t majorSubsystemVersion = 6;
302 uint32_t minorSubsystemVersion = 0;
303 uint32_t timestamp = 0;
304 uint32_t functionPadMin = 0;
305 uint32_t timeTraceGranularity = 0;
306 uint16_t dependentLoadFlags = 0;
307 bool dynamicBase = true;
308 bool allowBind = true;
309 bool cetCompat = false;
310 bool nxCompat = true;
311 bool allowIsolation = true;
312 bool terminalServerAware = true;
313 bool largeAddressAware = false;
314 bool highEntropyVA = false;
315 bool appContainer = false;
316 bool mingw = false;
317 bool warnMissingOrderSymbol = true;
318 bool warnLocallyDefinedImported = true;
319 bool warnDebugInfoUnusable = true;
320 bool warnLongSectionNames = true;
321 bool warnStdcallFixup = true;
322 bool warnImportedDllMain = true;
323 bool incremental = true;
324 bool integrityCheck = false;
325 bool killAt = false;
326 bool repro = false;
327 bool swaprunCD = false;
328 bool swaprunNet = false;
329 bool thinLTOEmitImportsFiles;
330 bool thinLTOIndexOnly;
331 bool timeTraceEnabled = false;
332 bool autoImport = false;
333 bool pseudoRelocs = false;
334 bool stdcallFixup = false;
335 bool writeCheckSum = false;
336 EmitKind emit = EmitKind::Obj;
337 bool allowDuplicateWeak = false;
338 BuildIDHash buildIDHash = BuildIDHash::None;
339};
340
341struct COFFSyncStream : SyncStream {
342 COFFLinkerContext &ctx;
343 COFFSyncStream(COFFLinkerContext &ctx, DiagLevel level);
344};
345
346template <typename T>
347std::enable_if_t<!std::is_pointer_v<std::remove_reference_t<T>>,
348 const COFFSyncStream &>
349operator<<(const COFFSyncStream &s, T &&v) {
350 s.os << std::forward<T>(v);
351 return s;
352}
353
354inline const COFFSyncStream &operator<<(const COFFSyncStream &s,
355 const char *v) {
356 s.os << v;
357 return s;
358}
359
360inline const COFFSyncStream &operator<<(const COFFSyncStream &s, Error v) {
361 s.os << llvm::toString(E: std::move(v));
362 return s;
363}
364
365// Report a log if -verbose is specified.
366COFFSyncStream Log(COFFLinkerContext &ctx);
367
368// Print a message to stdout.
369COFFSyncStream Msg(COFFLinkerContext &ctx);
370
371// Report a warning. Upgraded to an error if /WX is specified.
372COFFSyncStream Warn(COFFLinkerContext &ctx);
373
374// Report an error that will suppress the output file generation.
375COFFSyncStream Err(COFFLinkerContext &ctx);
376
377// Report a fatal error that exits immediately. This should generally be avoided
378// in favor of Err.
379COFFSyncStream Fatal(COFFLinkerContext &ctx);
380
381uint64_t errCount(COFFLinkerContext &ctx);
382
383} // namespace lld::coff
384
385#endif
386

source code of lld/COFF/Config.h