1 //===- Config.h -------------------------------------------------*- C++ -*-===//
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
7 //===----------------------------------------------------------------------===//
9 #ifndef LLD_COFF_CONFIG_H
10 #define LLD_COFF_CONFIG_H
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"
28 using llvm::COFF::IMAGE_FILE_MACHINE_UNKNOWN
;
29 using llvm::COFF::WindowsSubsystem
;
30 using llvm::StringRef
;
31 class COFFLinkerContext
;
32 class DefinedAbsolute
;
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
;
46 enum class ExportSource
{
53 enum class EmitKind
{ Obj
, LLVM
, ASM
};
55 // Represents an /export option.
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;
65 bool isPrivate
= false;
66 bool constant
= false;
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.
72 StringChunk
*forwardChunk
= nullptr;
74 ExportSource source
= ExportSource::Unset
;
76 StringRef exportName
; // Name in DLL
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
);
85 enum class DebugType
{
87 CV
= 0x1, /// CodeView
88 PData
= 0x2, /// Procedure Data
89 Fixup
= 0x4, /// Relocation Table
94 CF
= 0x1, /// Emit gfids tables
95 LongJmp
= 0x2, /// Emit longjmp tables
96 EHCont
= 0x4, /// Emit ehcont tables
97 All
= 0x7 /// Enable all protections
100 enum class ICFLevel
{
102 Safe
, // Safe ICF for all sections.
103 All
, // Aggressive ICF for code, but safe ICF for data, similar to MSVC's
107 enum class BuildIDHash
{
113 // Global configuration.
114 struct Configuration
{
115 enum ManifestKind
{ Default
, SideBySide
, Embed
, No
};
116 bool is64() const { return llvm::COFF::is64Bit(machine
); }
118 llvm::COFF::MachineTypes machine
= IMAGE_FILE_MACHINE_UNKNOWN
;
119 bool machineInferred
= false;
121 bool verbose
= false;
122 WindowsSubsystem subsystem
= llvm::COFF::IMAGE_SUBSYSTEM_UNKNOWN
;
123 Symbol
*entry
= nullptr;
124 bool noEntry
= false;
125 std::string outputFile
;
126 std::string importName
;
127 bool demangle
= true;
129 ICFLevel doICF
= ICFLevel::None
;
131 bool relocatable
= true;
132 bool forceMultiple
= false;
133 bool forceMultipleRes
= false;
134 bool forceUnresolved
= false;
136 bool includeDwarfChunks
= false;
137 bool debugGHashes
= false;
138 bool writeSymtab
= 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
;
155 // Symbols in this set are considered as live by the garbage collector.
156 std::vector
<Symbol
*> gcroot
;
158 std::set
<std::string
> noDefaultLibs
;
159 bool noDefaultLibAll
= false;
161 // True if we are creating a DLL.
164 bool noimplib
= false;
165 std::vector
<Export
> exports
;
166 bool hadExplicitExports
;
167 std::set
<std::string
> delayLoads
;
168 std::map
<std::string
, int> dllOrder
;
169 Symbol
*delayLoadHelper
= nullptr;
170 Symbol
*arm64ECIcallHelper
= nullptr;
172 llvm::DenseSet
<llvm::StringRef
> saveTempsArgs
;
175 int guardCF
= GuardCFLevel::Off
;
178 bool safeSEH
= false;
179 Symbol
*sehTable
= nullptr;
180 Symbol
*sehCount
= nullptr;
183 // Used for /opt:lldlto=N
185 // Used for /opt:lldltocgo=N
186 std::optional
<unsigned> ltoCgo
;
188 // Used for /opt:lldltojobs=N
189 std::string thinLTOJobs
;
190 // Used for /opt:lldltopartitions=N
191 unsigned ltoPartitions
= 1;
193 // Used for /lldltocache=path
195 // Used for /lldltocachepolicy=policy
196 llvm::CachePruningPolicy ltoCachePolicy
;
198 // Used for /opt:[no]ltodebugpassmanager
199 bool ltoDebugPassManager
= false;
201 // Used for /merge:from=to (e.g. /merge:.rdata=.text)
202 std::map
<StringRef
, StringRef
> merge
;
204 // Used for /section=.name,{DEKPRSW} to set section attributes.
205 std::map
<StringRef
, uint32_t> section
;
207 // Options for manifest files.
208 ManifestKind manifest
= Default
;
210 llvm::SetVector
<StringRef
> manifestDependencies
;
211 bool manifestUAC
= true;
212 std::vector
<std::string
> manifestInput
;
213 StringRef manifestLevel
= "'asInvoker'";
214 StringRef manifestUIAccess
= "'false'";
215 StringRef manifestFile
;
220 // Used for /aligncomm.
221 std::map
<std::string
, int> alignComm
;
223 // Used for /failifmismatch.
224 std::map
<StringRef
, std::pair
<StringRef
, InputFile
*>> mustMatch
;
226 // Used for /alternatename.
227 std::map
<StringRef
, StringRef
> alternateNames
;
230 llvm::StringMap
<int> order
;
233 std::string lldmapFile
;
238 // Used for /mapinfo.
239 bool mapInfo
= false;
241 // Used for /thinlto-index-only:
242 llvm::StringRef thinLTOIndexOnlyArg
;
244 // Used for /thinlto-prefix-replace:
245 // Replace the prefix in paths generated for ThinLTO, replacing
246 // thinLTOPrefixReplaceOld with thinLTOPrefixReplaceNew. If
247 // thinLTOPrefixReplaceNativeObject is defined, replace the prefix of object
248 // file paths written to the response file given in the
249 // --thinlto-index-only=${response} option with
250 // thinLTOPrefixReplaceNativeObject, instead of thinLTOPrefixReplaceNew.
251 llvm::StringRef thinLTOPrefixReplaceOld
;
252 llvm::StringRef thinLTOPrefixReplaceNew
;
253 llvm::StringRef thinLTOPrefixReplaceNativeObject
;
255 // Used for /thinlto-object-suffix-replace:
256 std::pair
<llvm::StringRef
, llvm::StringRef
> thinLTOObjectSuffixReplace
;
258 // Used for /lto-obj-path:
259 llvm::StringRef ltoObjPath
;
261 // Used for /lto-cs-profile-generate:
262 bool ltoCSProfileGenerate
= false;
264 // Used for /lto-cs-profile-path
265 llvm::StringRef ltoCSProfileFile
;
267 // Used for /lto-pgo-warn-mismatch:
268 bool ltoPGOWarnMismatch
= true;
270 // Used for /lto-sample-profile:
271 llvm::StringRef ltoSampleProfileName
;
273 // Used for /call-graph-ordering-file:
274 llvm::MapVector
<std::pair
<const SectionChunk
*, const SectionChunk
*>,
277 bool callGraphProfileSort
= false;
279 // Used for /print-symbol-order:
280 StringRef printSymbolOrder
;
282 // Used for /vfsoverlay:
283 std::unique_ptr
<llvm::vfs::FileSystem
> vfs
;
285 uint64_t align
= 4096;
286 uint64_t imageBase
= -1;
287 uint64_t fileAlign
= 512;
288 uint64_t stackReserve
= 1024 * 1024;
289 uint64_t stackCommit
= 4096;
290 uint64_t heapReserve
= 1024 * 1024;
291 uint64_t heapCommit
= 4096;
292 uint32_t majorImageVersion
= 0;
293 uint32_t minorImageVersion
= 0;
294 // If changing the default os/subsys version here, update the default in
295 // the MinGW driver accordingly.
296 uint32_t majorOSVersion
= 6;
297 uint32_t minorOSVersion
= 0;
298 uint32_t majorSubsystemVersion
= 6;
299 uint32_t minorSubsystemVersion
= 0;
300 uint32_t timestamp
= 0;
301 uint32_t functionPadMin
= 0;
302 uint32_t timeTraceGranularity
= 0;
303 uint16_t dependentLoadFlags
= 0;
304 bool dynamicBase
= true;
305 bool allowBind
= true;
306 bool cetCompat
= false;
307 bool nxCompat
= true;
308 bool allowIsolation
= true;
309 bool terminalServerAware
= true;
310 bool largeAddressAware
= false;
311 bool highEntropyVA
= false;
312 bool appContainer
= false;
314 bool warnMissingOrderSymbol
= true;
315 bool warnLocallyDefinedImported
= true;
316 bool warnDebugInfoUnusable
= true;
317 bool warnLongSectionNames
= true;
318 bool warnStdcallFixup
= true;
319 bool incremental
= true;
320 bool integrityCheck
= false;
323 bool swaprunCD
= false;
324 bool swaprunNet
= false;
325 bool thinLTOEmitImportsFiles
;
326 bool thinLTOIndexOnly
;
327 bool timeTraceEnabled
= false;
328 bool autoImport
= false;
329 bool pseudoRelocs
= false;
330 bool stdcallFixup
= false;
331 bool writeCheckSum
= false;
332 EmitKind emit
= EmitKind::Obj
;
333 bool allowDuplicateWeak
= false;
334 BuildIDHash buildIDHash
= BuildIDHash::None
;
337 struct COFFSyncStream
: SyncStream
{
338 COFFLinkerContext
&ctx
;
339 COFFSyncStream(COFFLinkerContext
&ctx
, DiagLevel level
);
342 template <typename T
>
343 std::enable_if_t
<!std::is_pointer_v
<std::remove_reference_t
<T
>>,
344 const COFFSyncStream
&>
345 operator<<(const COFFSyncStream
&s
, T
&&v
) {
346 s
.os
<< std::forward
<T
>(v
);
350 inline const COFFSyncStream
&operator<<(const COFFSyncStream
&s
,
356 inline const COFFSyncStream
&operator<<(const COFFSyncStream
&s
, Error v
) {
357 s
.os
<< llvm::toString(std::move(v
));
361 // Report a log if -verbose is specified.
362 COFFSyncStream
Log(COFFLinkerContext
&ctx
);
364 // Print a message to stdout.
365 COFFSyncStream
Msg(COFFLinkerContext
&ctx
);
367 // Report a warning. Upgraded to an error if /WX is specified.
368 COFFSyncStream
Warn(COFFLinkerContext
&ctx
);
370 // Report an error that will suppress the output file generation.
371 COFFSyncStream
Err(COFFLinkerContext
&ctx
);
373 // Report a fatal error that exits immediately. This should generally be avoided
375 COFFSyncStream
Fatal(COFFLinkerContext
&ctx
);
377 uint64_t errCount(COFFLinkerContext
&ctx
);
379 } // namespace lld::coff