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