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