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