xref: /freebsd/contrib/llvm-project/lld/COFF/Config.h (revision e64bea71c21eb42e97aa615188ba91f6cce0d36d)
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 
26 namespace lld::coff {
27 
28 using llvm::COFF::IMAGE_FILE_MACHINE_UNKNOWN;
29 using llvm::COFF::WindowsSubsystem;
30 using llvm::StringRef;
31 class COFFLinkerContext;
32 class DefinedAbsolute;
33 class StringChunk;
34 class Symbol;
35 class InputFile;
36 class SectionChunk;
37 
38 // Short aliases.
39 static const auto AMD64 = llvm::COFF::IMAGE_FILE_MACHINE_AMD64;
40 static const auto ARM64 = llvm::COFF::IMAGE_FILE_MACHINE_ARM64;
41 static const auto ARM64EC = llvm::COFF::IMAGE_FILE_MACHINE_ARM64EC;
42 static const auto ARM64X = llvm::COFF::IMAGE_FILE_MACHINE_ARM64X;
43 static const auto ARMNT = llvm::COFF::IMAGE_FILE_MACHINE_ARMNT;
44 static const auto I386 = llvm::COFF::IMAGE_FILE_MACHINE_I386;
45 
46 enum class ExportSource {
47   Unset,
48   Directives,
49   Export,
50   ModuleDefinition,
51 };
52 
53 enum class EmitKind { Obj, LLVM, ASM };
54 
55 // Represents an /export option.
56 struct 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 
85 enum class DebugType {
86   None  = 0x0,
87   CV    = 0x1,  /// CodeView
88   PData = 0x2,  /// Procedure Data
89   Fixup = 0x4,  /// Relocation Table
90 };
91 
92 enum 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 
100 enum 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 
107 enum class BuildIDHash {
108   None,
109   PDB,
110   Binary,
111 };
112 
113 // Global configuration.
114 struct Configuration {
115   enum ManifestKind { Default, SideBySide, Embed, No };
is64Configuration116   bool is64() const { return llvm::COFF::is64Bit(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 
341 struct COFFSyncStream : SyncStream {
342   COFFLinkerContext &ctx;
343   COFFSyncStream(COFFLinkerContext &ctx, DiagLevel level);
344 };
345 
346 template <typename T>
347 std::enable_if_t<!std::is_pointer_v<std::remove_reference_t<T>>,
348                  const COFFSyncStream &>
349 operator<<(const COFFSyncStream &s, T &&v) {
350   s.os << std::forward<T>(v);
351   return s;
352 }
353 
354 inline const COFFSyncStream &operator<<(const COFFSyncStream &s,
355                                         const char *v) {
356   s.os << v;
357   return s;
358 }
359 
360 inline const COFFSyncStream &operator<<(const COFFSyncStream &s, Error v) {
361   s.os << llvm::toString(std::move(v));
362   return s;
363 }
364 
365 // Report a log if -verbose is specified.
366 COFFSyncStream Log(COFFLinkerContext &ctx);
367 
368 // Print a message to stdout.
369 COFFSyncStream Msg(COFFLinkerContext &ctx);
370 
371 // Report a warning. Upgraded to an error if /WX is specified.
372 COFFSyncStream Warn(COFFLinkerContext &ctx);
373 
374 // Report an error that will suppress the output file generation.
375 COFFSyncStream Err(COFFLinkerContext &ctx);
376 
377 // Report a fatal error that exits immediately. This should generally be avoided
378 // in favor of Err.
379 COFFSyncStream Fatal(COFFLinkerContext &ctx);
380 
381 uint64_t errCount(COFFLinkerContext &ctx);
382 
383 } // namespace lld::coff
384 
385 #endif
386