xref: /freebsd/contrib/llvm-project/lld/COFF/Config.h (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
10b57cec5SDimitry Andric //===- Config.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_CONFIG_H
100b57cec5SDimitry Andric #define LLD_COFF_CONFIG_H
110b57cec5SDimitry Andric 
12e8d8bef9SDimitry Andric #include "llvm/ADT/MapVector.h"
13349cc55cSDimitry Andric #include "llvm/ADT/SetVector.h"
14bdd1243dSDimitry Andric #include "llvm/ADT/SmallVector.h"
150b57cec5SDimitry Andric #include "llvm/ADT/StringMap.h"
160b57cec5SDimitry Andric #include "llvm/ADT/StringRef.h"
170b57cec5SDimitry Andric #include "llvm/Object/COFF.h"
180b57cec5SDimitry Andric #include "llvm/Support/CachePruning.h"
19753f127fSDimitry Andric #include "llvm/Support/VirtualFileSystem.h"
200b57cec5SDimitry Andric #include <cstdint>
210b57cec5SDimitry Andric #include <map>
220b57cec5SDimitry Andric #include <set>
230b57cec5SDimitry Andric #include <string>
240b57cec5SDimitry Andric 
25bdd1243dSDimitry Andric namespace lld::coff {
260b57cec5SDimitry Andric 
270b57cec5SDimitry Andric using llvm::COFF::IMAGE_FILE_MACHINE_UNKNOWN;
280b57cec5SDimitry Andric using llvm::COFF::WindowsSubsystem;
290b57cec5SDimitry Andric using llvm::StringRef;
300b57cec5SDimitry Andric class DefinedAbsolute;
310b57cec5SDimitry Andric class StringChunk;
320b57cec5SDimitry Andric class Symbol;
330b57cec5SDimitry Andric class InputFile;
34e8d8bef9SDimitry Andric class SectionChunk;
350b57cec5SDimitry Andric 
360b57cec5SDimitry Andric // Short aliases.
370b57cec5SDimitry Andric static const auto AMD64 = llvm::COFF::IMAGE_FILE_MACHINE_AMD64;
380b57cec5SDimitry Andric static const auto ARM64 = llvm::COFF::IMAGE_FILE_MACHINE_ARM64;
3906c3fb27SDimitry Andric static const auto ARM64EC = llvm::COFF::IMAGE_FILE_MACHINE_ARM64EC;
4006c3fb27SDimitry Andric static const auto ARM64X = llvm::COFF::IMAGE_FILE_MACHINE_ARM64X;
410b57cec5SDimitry Andric static const auto ARMNT = llvm::COFF::IMAGE_FILE_MACHINE_ARMNT;
420b57cec5SDimitry Andric static const auto I386 = llvm::COFF::IMAGE_FILE_MACHINE_I386;
430b57cec5SDimitry Andric 
4406c3fb27SDimitry Andric enum class ExportSource {
4506c3fb27SDimitry Andric   Unset,
4606c3fb27SDimitry Andric   Directives,
4706c3fb27SDimitry Andric   Export,
4806c3fb27SDimitry Andric   ModuleDefinition,
4906c3fb27SDimitry Andric };
5006c3fb27SDimitry Andric 
515f757f3fSDimitry Andric enum class EmitKind { Obj, LLVM, ASM };
525f757f3fSDimitry Andric 
530b57cec5SDimitry Andric // Represents an /export option.
540b57cec5SDimitry Andric struct Export {
550b57cec5SDimitry Andric   StringRef name;       // N in /export:N or /export:E=N
560b57cec5SDimitry Andric   StringRef extName;    // E in /export:E=N
57*0fca6ea1SDimitry Andric   StringRef exportAs;   // E in /export:N,EXPORTAS,E
58*0fca6ea1SDimitry Andric   StringRef importName; // GNU specific: N in "othername == N"
590b57cec5SDimitry Andric   Symbol *sym = nullptr;
600b57cec5SDimitry Andric   uint16_t ordinal = 0;
610b57cec5SDimitry Andric   bool noname = false;
620b57cec5SDimitry Andric   bool data = false;
630b57cec5SDimitry Andric   bool isPrivate = false;
640b57cec5SDimitry Andric   bool constant = false;
650b57cec5SDimitry Andric 
660b57cec5SDimitry Andric   // If an export is a form of /export:foo=dllname.bar, that means
670b57cec5SDimitry Andric   // that foo should be exported as an alias to bar in the DLL.
680b57cec5SDimitry Andric   // forwardTo is set to "dllname.bar" part. Usually empty.
690b57cec5SDimitry Andric   StringRef forwardTo;
700b57cec5SDimitry Andric   StringChunk *forwardChunk = nullptr;
710b57cec5SDimitry Andric 
7206c3fb27SDimitry Andric   ExportSource source = ExportSource::Unset;
730b57cec5SDimitry Andric   StringRef symbolName;
740b57cec5SDimitry Andric   StringRef exportName; // Name in DLL
750b57cec5SDimitry Andric 
765f757f3fSDimitry Andric   bool operator==(const Export &e) const {
77*0fca6ea1SDimitry Andric     return (name == e.name && extName == e.extName && exportAs == e.exportAs &&
78*0fca6ea1SDimitry Andric             importName == e.importName && ordinal == e.ordinal &&
79*0fca6ea1SDimitry Andric             noname == e.noname && data == e.data && isPrivate == e.isPrivate);
800b57cec5SDimitry Andric   }
810b57cec5SDimitry Andric };
820b57cec5SDimitry Andric 
830b57cec5SDimitry Andric enum class DebugType {
840b57cec5SDimitry Andric   None  = 0x0,
850b57cec5SDimitry Andric   CV    = 0x1,  /// CodeView
860b57cec5SDimitry Andric   PData = 0x2,  /// Procedure Data
870b57cec5SDimitry Andric   Fixup = 0x4,  /// Relocation Table
880b57cec5SDimitry Andric };
890b57cec5SDimitry Andric 
90fe6060f1SDimitry Andric enum GuardCFLevel {
91fe6060f1SDimitry Andric   Off     = 0x0,
92fe6060f1SDimitry Andric   CF      = 0x1, /// Emit gfids tables
93fe6060f1SDimitry Andric   LongJmp = 0x2, /// Emit longjmp tables
94fe6060f1SDimitry Andric   EHCont  = 0x4, /// Emit ehcont tables
95fe6060f1SDimitry Andric   All     = 0x7  /// Enable all protections
96fe6060f1SDimitry Andric };
97fe6060f1SDimitry Andric 
98fe6060f1SDimitry Andric enum class ICFLevel {
99fe6060f1SDimitry Andric   None,
100fe6060f1SDimitry Andric   Safe, // Safe ICF for all sections.
101fe6060f1SDimitry Andric   All,  // Aggressive ICF for code, but safe ICF for data, similar to MSVC's
102fe6060f1SDimitry Andric         // behavior.
1030b57cec5SDimitry Andric };
1040b57cec5SDimitry Andric 
1055f757f3fSDimitry Andric enum class BuildIDHash {
1065f757f3fSDimitry Andric   None,
1075f757f3fSDimitry Andric   PDB,
1085f757f3fSDimitry Andric   Binary,
1095f757f3fSDimitry Andric };
1105f757f3fSDimitry Andric 
1110b57cec5SDimitry Andric // Global configuration.
1120b57cec5SDimitry Andric struct Configuration {
113349cc55cSDimitry Andric   enum ManifestKind { Default, SideBySide, Embed, No };
is64Configuration1145f757f3fSDimitry Andric   bool is64() const { return llvm::COFF::is64Bit(machine); }
1150b57cec5SDimitry Andric 
1160b57cec5SDimitry Andric   llvm::COFF::MachineTypes machine = IMAGE_FILE_MACHINE_UNKNOWN;
1170b57cec5SDimitry Andric   size_t wordsize;
1180b57cec5SDimitry Andric   bool verbose = false;
1190b57cec5SDimitry Andric   WindowsSubsystem subsystem = llvm::COFF::IMAGE_SUBSYSTEM_UNKNOWN;
1200b57cec5SDimitry Andric   Symbol *entry = nullptr;
1210b57cec5SDimitry Andric   bool noEntry = false;
1220b57cec5SDimitry Andric   std::string outputFile;
1230b57cec5SDimitry Andric   std::string importName;
1240b57cec5SDimitry Andric   bool demangle = true;
1250b57cec5SDimitry Andric   bool doGC = true;
126fe6060f1SDimitry Andric   ICFLevel doICF = ICFLevel::None;
1270b57cec5SDimitry Andric   bool tailMerge;
1280b57cec5SDimitry Andric   bool relocatable = true;
1290b57cec5SDimitry Andric   bool forceMultiple = false;
1300b57cec5SDimitry Andric   bool forceMultipleRes = false;
1310b57cec5SDimitry Andric   bool forceUnresolved = false;
1320b57cec5SDimitry Andric   bool debug = false;
1335f757f3fSDimitry Andric   bool includeDwarfChunks = false;
1340b57cec5SDimitry Andric   bool debugGHashes = false;
1355f757f3fSDimitry Andric   bool writeSymtab = false;
136480093f4SDimitry Andric   bool driver = false;
137480093f4SDimitry Andric   bool driverUponly = false;
138480093f4SDimitry Andric   bool driverWdm = false;
1390b57cec5SDimitry Andric   bool showTiming = false;
1400b57cec5SDimitry Andric   bool showSummary = false;
14106c3fb27SDimitry Andric   bool printSearchPaths = false;
1420b57cec5SDimitry Andric   unsigned debugTypes = static_cast<unsigned>(DebugType::None);
143bdd1243dSDimitry Andric   llvm::SmallVector<llvm::StringRef, 0> mllvmOpts;
1440b57cec5SDimitry Andric   std::vector<std::string> natvisFiles;
1455ffd83dbSDimitry Andric   llvm::StringMap<std::string> namedStreams;
1460b57cec5SDimitry Andric   llvm::SmallString<128> pdbAltPath;
147349cc55cSDimitry Andric   int pdbPageSize = 4096;
1480b57cec5SDimitry Andric   llvm::SmallString<128> pdbPath;
1490b57cec5SDimitry Andric   llvm::SmallString<128> pdbSourcePath;
1500b57cec5SDimitry Andric   std::vector<llvm::StringRef> argv;
1510b57cec5SDimitry Andric 
1520b57cec5SDimitry Andric   // Symbols in this set are considered as live by the garbage collector.
1530b57cec5SDimitry Andric   std::vector<Symbol *> gcroot;
1540b57cec5SDimitry Andric 
1550b57cec5SDimitry Andric   std::set<std::string> noDefaultLibs;
1560b57cec5SDimitry Andric   bool noDefaultLibAll = false;
1570b57cec5SDimitry Andric 
1580b57cec5SDimitry Andric   // True if we are creating a DLL.
1590b57cec5SDimitry Andric   bool dll = false;
1600b57cec5SDimitry Andric   StringRef implib;
16181ad6265SDimitry Andric   bool noimplib = false;
1620b57cec5SDimitry Andric   std::vector<Export> exports;
16385868e8aSDimitry Andric   bool hadExplicitExports;
1640b57cec5SDimitry Andric   std::set<std::string> delayLoads;
1650b57cec5SDimitry Andric   std::map<std::string, int> dllOrder;
1660b57cec5SDimitry Andric   Symbol *delayLoadHelper = nullptr;
1670b57cec5SDimitry Andric 
1680b57cec5SDimitry Andric   bool saveTemps = false;
1690b57cec5SDimitry Andric 
1700b57cec5SDimitry Andric   // /guard:cf
171fe6060f1SDimitry Andric   int guardCF = GuardCFLevel::Off;
1720b57cec5SDimitry Andric 
1730b57cec5SDimitry Andric   // Used for SafeSEH.
1740b57cec5SDimitry Andric   bool safeSEH = false;
1750b57cec5SDimitry Andric   Symbol *sehTable = nullptr;
1760b57cec5SDimitry Andric   Symbol *sehCount = nullptr;
177979e22ffSDimitry Andric   bool noSEH = false;
1780b57cec5SDimitry Andric 
1790b57cec5SDimitry Andric   // Used for /opt:lldlto=N
1800b57cec5SDimitry Andric   unsigned ltoo = 2;
18106c3fb27SDimitry Andric   // Used for /opt:lldltocgo=N
18206c3fb27SDimitry Andric   std::optional<unsigned> ltoCgo;
1830b57cec5SDimitry Andric 
1840b57cec5SDimitry Andric   // Used for /opt:lldltojobs=N
1855ffd83dbSDimitry Andric   std::string thinLTOJobs;
1860b57cec5SDimitry Andric   // Used for /opt:lldltopartitions=N
1870b57cec5SDimitry Andric   unsigned ltoPartitions = 1;
1880b57cec5SDimitry Andric 
1891db9f3b2SDimitry Andric   // Used for /lldltocache=path
1900b57cec5SDimitry Andric   StringRef ltoCache;
1911db9f3b2SDimitry Andric   // Used for /lldltocachepolicy=policy
1920b57cec5SDimitry Andric   llvm::CachePruningPolicy ltoCachePolicy;
1930b57cec5SDimitry Andric 
194e8d8bef9SDimitry Andric   // Used for /opt:[no]ltodebugpassmanager
195e8d8bef9SDimitry Andric   bool ltoDebugPassManager = false;
196e8d8bef9SDimitry Andric 
1970b57cec5SDimitry Andric   // Used for /merge:from=to (e.g. /merge:.rdata=.text)
1980b57cec5SDimitry Andric   std::map<StringRef, StringRef> merge;
1990b57cec5SDimitry Andric 
2000b57cec5SDimitry Andric   // Used for /section=.name,{DEKPRSW} to set section attributes.
2010b57cec5SDimitry Andric   std::map<StringRef, uint32_t> section;
2020b57cec5SDimitry Andric 
2030b57cec5SDimitry Andric   // Options for manifest files.
204349cc55cSDimitry Andric   ManifestKind manifest = Default;
2050b57cec5SDimitry Andric   int manifestID = 1;
206349cc55cSDimitry Andric   llvm::SetVector<StringRef> manifestDependencies;
2070b57cec5SDimitry Andric   bool manifestUAC = true;
2080b57cec5SDimitry Andric   std::vector<std::string> manifestInput;
2090b57cec5SDimitry Andric   StringRef manifestLevel = "'asInvoker'";
2100b57cec5SDimitry Andric   StringRef manifestUIAccess = "'false'";
2110b57cec5SDimitry Andric   StringRef manifestFile;
2120b57cec5SDimitry Andric 
21306c3fb27SDimitry Andric   // used for /dwodir
21406c3fb27SDimitry Andric   StringRef dwoDir;
21506c3fb27SDimitry Andric 
2160b57cec5SDimitry Andric   // Used for /aligncomm.
2170b57cec5SDimitry Andric   std::map<std::string, int> alignComm;
2180b57cec5SDimitry Andric 
2190b57cec5SDimitry Andric   // Used for /failifmismatch.
2200b57cec5SDimitry Andric   std::map<StringRef, std::pair<StringRef, InputFile *>> mustMatch;
2210b57cec5SDimitry Andric 
2220b57cec5SDimitry Andric   // Used for /alternatename.
2230b57cec5SDimitry Andric   std::map<StringRef, StringRef> alternateNames;
2240b57cec5SDimitry Andric 
2250b57cec5SDimitry Andric   // Used for /order.
2260b57cec5SDimitry Andric   llvm::StringMap<int> order;
2270b57cec5SDimitry Andric 
2280b57cec5SDimitry Andric   // Used for /lldmap.
2295ffd83dbSDimitry Andric   std::string lldmapFile;
2305ffd83dbSDimitry Andric 
2315ffd83dbSDimitry Andric   // Used for /map.
2320b57cec5SDimitry Andric   std::string mapFile;
2330b57cec5SDimitry Andric 
234bdd1243dSDimitry Andric   // Used for /mapinfo.
235bdd1243dSDimitry Andric   bool mapInfo = false;
236bdd1243dSDimitry Andric 
2370b57cec5SDimitry Andric   // Used for /thinlto-index-only:
2380b57cec5SDimitry Andric   llvm::StringRef thinLTOIndexOnlyArg;
2390b57cec5SDimitry Andric 
24006c3fb27SDimitry Andric   // Used for /thinlto-prefix-replace:
24106c3fb27SDimitry Andric   // Replace the prefix in paths generated for ThinLTO, replacing
24206c3fb27SDimitry Andric   // thinLTOPrefixReplaceOld with thinLTOPrefixReplaceNew. If
24306c3fb27SDimitry Andric   // thinLTOPrefixReplaceNativeObject is defined, replace the prefix of object
24406c3fb27SDimitry Andric   // file paths written to the response file given in the
24506c3fb27SDimitry Andric   // --thinlto-index-only=${response} option with
24606c3fb27SDimitry Andric   // thinLTOPrefixReplaceNativeObject, instead of thinLTOPrefixReplaceNew.
24706c3fb27SDimitry Andric   llvm::StringRef thinLTOPrefixReplaceOld;
24806c3fb27SDimitry Andric   llvm::StringRef thinLTOPrefixReplaceNew;
24906c3fb27SDimitry Andric   llvm::StringRef thinLTOPrefixReplaceNativeObject;
2500b57cec5SDimitry Andric 
2510b57cec5SDimitry Andric   // Used for /thinlto-object-suffix-replace:
2520b57cec5SDimitry Andric   std::pair<llvm::StringRef, llvm::StringRef> thinLTOObjectSuffixReplace;
2530b57cec5SDimitry Andric 
25485868e8aSDimitry Andric   // Used for /lto-obj-path:
25585868e8aSDimitry Andric   llvm::StringRef ltoObjPath;
25685868e8aSDimitry Andric 
257fe6060f1SDimitry Andric   // Used for /lto-cs-profile-generate:
258fe6060f1SDimitry Andric   bool ltoCSProfileGenerate = false;
259fe6060f1SDimitry Andric 
260fe6060f1SDimitry Andric   // Used for /lto-cs-profile-path
261fe6060f1SDimitry Andric   llvm::StringRef ltoCSProfileFile;
262fe6060f1SDimitry Andric 
263349cc55cSDimitry Andric   // Used for /lto-pgo-warn-mismatch:
264349cc55cSDimitry Andric   bool ltoPGOWarnMismatch = true;
265349cc55cSDimitry Andric 
266*0fca6ea1SDimitry Andric   // Used for /lto-sample-profile:
267*0fca6ea1SDimitry Andric   llvm::StringRef ltoSampleProfileName;
268*0fca6ea1SDimitry Andric 
269e8d8bef9SDimitry Andric   // Used for /call-graph-ordering-file:
270e8d8bef9SDimitry Andric   llvm::MapVector<std::pair<const SectionChunk *, const SectionChunk *>,
271e8d8bef9SDimitry Andric                   uint64_t>
272e8d8bef9SDimitry Andric       callGraphProfile;
273e8d8bef9SDimitry Andric   bool callGraphProfileSort = false;
274e8d8bef9SDimitry Andric 
275e8d8bef9SDimitry Andric   // Used for /print-symbol-order:
276e8d8bef9SDimitry Andric   StringRef printSymbolOrder;
277e8d8bef9SDimitry Andric 
278753f127fSDimitry Andric   // Used for /vfsoverlay:
279753f127fSDimitry Andric   std::unique_ptr<llvm::vfs::FileSystem> vfs;
280753f127fSDimitry Andric 
2810b57cec5SDimitry Andric   uint64_t align = 4096;
2820b57cec5SDimitry Andric   uint64_t imageBase = -1;
2830b57cec5SDimitry Andric   uint64_t fileAlign = 512;
2840b57cec5SDimitry Andric   uint64_t stackReserve = 1024 * 1024;
2850b57cec5SDimitry Andric   uint64_t stackCommit = 4096;
2860b57cec5SDimitry Andric   uint64_t heapReserve = 1024 * 1024;
2870b57cec5SDimitry Andric   uint64_t heapCommit = 4096;
2880b57cec5SDimitry Andric   uint32_t majorImageVersion = 0;
2890b57cec5SDimitry Andric   uint32_t minorImageVersion = 0;
290e8d8bef9SDimitry Andric   // If changing the default os/subsys version here, update the default in
291e8d8bef9SDimitry Andric   // the MinGW driver accordingly.
2920b57cec5SDimitry Andric   uint32_t majorOSVersion = 6;
2930b57cec5SDimitry Andric   uint32_t minorOSVersion = 0;
294e8d8bef9SDimitry Andric   uint32_t majorSubsystemVersion = 6;
295e8d8bef9SDimitry Andric   uint32_t minorSubsystemVersion = 0;
2960b57cec5SDimitry Andric   uint32_t timestamp = 0;
2970b57cec5SDimitry Andric   uint32_t functionPadMin = 0;
2985f757f3fSDimitry Andric   uint32_t timeTraceGranularity = 0;
2995f757f3fSDimitry Andric   uint16_t dependentLoadFlags = 0;
3000b57cec5SDimitry Andric   bool dynamicBase = true;
3010b57cec5SDimitry Andric   bool allowBind = true;
3025ffd83dbSDimitry Andric   bool cetCompat = false;
3030b57cec5SDimitry Andric   bool nxCompat = true;
3040b57cec5SDimitry Andric   bool allowIsolation = true;
3050b57cec5SDimitry Andric   bool terminalServerAware = true;
3060b57cec5SDimitry Andric   bool largeAddressAware = false;
3070b57cec5SDimitry Andric   bool highEntropyVA = false;
3080b57cec5SDimitry Andric   bool appContainer = false;
3090b57cec5SDimitry Andric   bool mingw = false;
3100b57cec5SDimitry Andric   bool warnMissingOrderSymbol = true;
3110b57cec5SDimitry Andric   bool warnLocallyDefinedImported = true;
3120b57cec5SDimitry Andric   bool warnDebugInfoUnusable = true;
313480093f4SDimitry Andric   bool warnLongSectionNames = true;
314fe6060f1SDimitry Andric   bool warnStdcallFixup = true;
3150b57cec5SDimitry Andric   bool incremental = true;
3160b57cec5SDimitry Andric   bool integrityCheck = false;
3170b57cec5SDimitry Andric   bool killAt = false;
3180b57cec5SDimitry Andric   bool repro = false;
3190b57cec5SDimitry Andric   bool swaprunCD = false;
3200b57cec5SDimitry Andric   bool swaprunNet = false;
3210b57cec5SDimitry Andric   bool thinLTOEmitImportsFiles;
3220b57cec5SDimitry Andric   bool thinLTOIndexOnly;
3235f757f3fSDimitry Andric   bool timeTraceEnabled = false;
3245ffd83dbSDimitry Andric   bool autoImport = false;
3255ffd83dbSDimitry Andric   bool pseudoRelocs = false;
326fe6060f1SDimitry Andric   bool stdcallFixup = false;
327bdd1243dSDimitry Andric   bool writeCheckSum = false;
3285f757f3fSDimitry Andric   EmitKind emit = EmitKind::Obj;
3295f757f3fSDimitry Andric   bool allowDuplicateWeak = false;
3305f757f3fSDimitry Andric   BuildIDHash buildIDHash = BuildIDHash::None;
3310b57cec5SDimitry Andric };
3320b57cec5SDimitry Andric 
333bdd1243dSDimitry Andric } // namespace lld::coff
3340b57cec5SDimitry Andric 
3350b57cec5SDimitry Andric #endif
336