blob: 473943a2394228f95b4be912d2de04913fd22ed8 [file] [log] [blame]
Rafael Espindolabeee25e2015-08-14 14:12:541//===- Config.h -------------------------------------------------*- C++ -*-===//
Rui Ueyama411c63602015-05-28 19:09:302//
Chandler Carruth2946cd72019-01-19 08:50:563// 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
Rui Ueyama411c63602015-05-28 19:09:306//
7//===----------------------------------------------------------------------===//
8
9#ifndef LLD_COFF_CONFIG_H
10#define LLD_COFF_CONFIG_H
11
Fangrui Song982575fd2024-12-04 04:51:5012#include "lld/Common/ErrorHandler.h"
Zequan Wu763671f2020-07-21 20:46:1113#include "llvm/ADT/MapVector.h"
Nico Weber400a1de2021-08-24 14:19:2114#include "llvm/ADT/SetVector.h"
Nico Weber67d311a2022-11-14 19:23:5615#include "llvm/ADT/SmallVector.h"
Rui Ueyama57175aa2018-01-27 00:34:4616#include "llvm/ADT/StringMap.h"
Rui Ueyama411c63602015-05-28 19:09:3017#include "llvm/ADT/StringRef.h"
Rui Ueyama3d3e6fb2015-05-29 16:06:0018#include "llvm/Object/COFF.h"
Peter Collingbourne052e855e2017-09-08 00:50:5019#include "llvm/Support/CachePruning.h"
Alex Brachetfd9962e2022-07-11 21:31:0120#include "llvm/Support/VirtualFileSystem.h"
Rui Ueyama411c63602015-05-28 19:09:3021#include <cstdint>
Rui Ueyama8854d8a2015-06-04 19:21:2422#include <map>
Rui Ueyama411c63602015-05-28 19:09:3023#include <set>
24#include <string>
25
Nico Weber7c266412022-08-08 15:32:2626namespace lld::coff {
Rui Ueyama411c63602015-05-28 19:09:3027
Rui Ueyamae16a75d52015-07-08 18:14:5128using llvm::COFF::IMAGE_FILE_MACHINE_UNKNOWN;
Rui Ueyama15cc47e2015-05-29 16:34:3129using llvm::COFF::WindowsSubsystem;
Rui Ueyamad21b00b2015-05-31 19:17:1430using llvm::StringRef;
Fangrui Song982575fd2024-12-04 04:51:5031class COFFLinkerContext;
Rui Ueyamacd3f99b2015-07-24 23:51:1432class DefinedAbsolute;
Rui Ueyama84425d72016-01-09 01:22:0033class StringChunk;
Rui Ueyamaf52496e2017-11-03 21:21:4734class Symbol;
Alexandre Ganea347a45c2019-03-29 19:58:5835class InputFile;
Zequan Wu763671f2020-07-21 20:46:1136class SectionChunk;
Rui Ueyama15cc47e2015-05-29 16:34:3137
Rui Ueyama35ccb0f2015-07-25 00:20:0638// Short aliases.
39static const auto AMD64 = llvm::COFF::IMAGE_FILE_MACHINE_AMD64;
Martin Storsjo94fce502017-07-01 20:29:2740static const auto ARM64 = llvm::COFF::IMAGE_FILE_MACHINE_ARM64;
Jacek Caban482ee332023-03-21 19:01:2241static const auto ARM64EC = llvm::COFF::IMAGE_FILE_MACHINE_ARM64EC;
42static const auto ARM64X = llvm::COFF::IMAGE_FILE_MACHINE_ARM64X;
Rui Ueyamaa265b012015-07-25 02:25:1443static const auto ARMNT = llvm::COFF::IMAGE_FILE_MACHINE_ARMNT;
Rui Ueyama35ccb0f2015-07-25 00:20:0644static const auto I386 = llvm::COFF::IMAGE_FILE_MACHINE_I386;
45
Alexandre Ganeaadcdc9c2023-06-13 19:12:5546enum class ExportSource {
47 Unset,
48 Directives,
49 Export,
50 ModuleDefinition,
51};
52
Matheus Izvekovd12b99a2023-10-03 23:24:5453enum class EmitKind { Obj, LLVM, ASM };
Matheus Izvekov3923e612023-10-02 20:54:4354
Rui Ueyama97dff9e2015-06-17 00:16:3355// Represents an /export option.
56struct Export {
Rui Ueyama136d27a2019-07-11 05:40:3057 StringRef name; // N in /export:N or /export:E=N
58 StringRef extName; // E in /export:E=N
Jacek Cabancc23ee82024-03-27 10:37:0259 StringRef exportAs; // E in /export:N,EXPORTAS,E
Martin Storsjö750de322024-04-18 10:29:3860 StringRef importName; // GNU specific: N in "othername == N"
Rui Ueyama136d27a2019-07-11 05:40:3061 Symbol *sym = nullptr;
62 uint16_t ordinal = 0;
63 bool noname = false;
64 bool data = false;
65 bool isPrivate = false;
66 bool constant = false;
Rui Ueyama4b8cdd202015-07-03 23:23:2967
Rui Ueyama84425d72016-01-09 01:22:0068 // 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.
Fangrui Song2e2038b2019-07-16 08:26:3870 // forwardTo is set to "dllname.bar" part. Usually empty.
Rui Ueyama136d27a2019-07-11 05:40:3071 StringRef forwardTo;
72 StringChunk *forwardChunk = nullptr;
Rui Ueyama84425d72016-01-09 01:22:0073
Alexandre Ganeaadcdc9c2023-06-13 19:12:5574 ExportSource source = ExportSource::Unset;
Rui Ueyama136d27a2019-07-11 05:40:3075 StringRef symbolName;
76 StringRef exportName; // Name in DLL
Rui Ueyamaf10a3202015-08-31 08:43:2177
Samira Bazuzi8899b712023-10-04 15:39:2078 bool operator==(const Export &e) const {
Jacek Cabancc23ee82024-03-27 10:37:0279 return (name == e.name && extName == e.extName && exportAs == e.exportAs &&
Martin Storsjö750de322024-04-18 10:29:3880 importName == e.importName && ordinal == e.ordinal &&
Jacek Cabancc23ee82024-03-27 10:37:0281 noname == e.noname && data == e.data && isPrivate == e.isPrivate);
Rui Ueyama4b8cdd202015-07-03 23:23:2982 }
Rui Ueyama97dff9e2015-06-17 00:16:3383};
84
Saleem Abdulrasoola2cca7e2016-08-08 22:02:4485enum class DebugType {
86 None = 0x0,
87 CV = 0x1, /// CodeView
88 PData = 0x2, /// Procedure Data
89 Fixup = 0x4, /// Relocation Table
90};
91
Pengfei Wang184377d2021-04-14 06:21:5292enum GuardCFLevel {
93 Off = 0x0,
94 CF = 0x1, /// Emit gfids tables
95 LongJmp = 0x2, /// Emit longjmp tables
96 EHCont = 0x4, /// Emit ehcont tables
97 All = 0x7 /// Enable all protections
Reid Klecknerfd520962018-02-13 20:32:5398};
99
Zequan Wu5bdc5e72021-02-27 00:38:24100enum class ICFLevel {
101 None,
102 Safe, // Safe ICF for all sections.
103 All, // Aggressive ICF for code, but safe ICF for data, similar to MSVC's
104 // behavior.
105};
106
Zequan Wuaaf3a8d2023-12-05 19:57:45107enum class BuildIDHash {
108 None,
109 PDB,
110 Binary,
111};
112
Rui Ueyama97dff9e2015-06-17 00:16:33113// Global configuration.
114struct Configuration {
Nico Weber400a1de2021-08-24 14:19:21115 enum ManifestKind { Default, SideBySide, Embed, No };
Jacek Cabanca348122023-04-28 12:35:38116 bool is64() const { return llvm::COFF::is64Bit(machine); }
Rui Ueyama24c5fd02015-06-18 00:12:42117
kkent030315fb974e82025-01-20 21:38:59118 std::unique_ptr<MemoryBuffer> dosStub;
Rui Ueyama136d27a2019-07-11 05:40:30119 llvm::COFF::MachineTypes machine = IMAGE_FILE_MACHINE_UNKNOWN;
Jacek Cabanf9429492024-11-24 13:33:14120 bool machineInferred = false;
Rui Ueyama136d27a2019-07-11 05:40:30121 size_t wordsize;
122 bool verbose = false;
123 WindowsSubsystem subsystem = llvm::COFF::IMAGE_SUBSYSTEM_UNKNOWN;
Rui Ueyama136d27a2019-07-11 05:40:30124 bool noEntry = false;
125 std::string outputFile;
126 std::string importName;
127 bool demangle = true;
128 bool doGC = true;
Zequan Wu5bdc5e72021-02-27 00:38:24129 ICFLevel doICF = ICFLevel::None;
Rui Ueyama136d27a2019-07-11 05:40:30130 bool tailMerge;
131 bool relocatable = true;
132 bool forceMultiple = false;
133 bool forceMultipleRes = false;
134 bool forceUnresolved = false;
135 bool debug = false;
Martin Storsjö23e6e882023-12-15 18:01:13136 bool includeDwarfChunks = false;
Rui Ueyama136d27a2019-07-11 05:40:30137 bool debugGHashes = false;
Martin Storsjö23e6e882023-12-15 18:01:13138 bool writeSymtab = false;
Rui Ueyamaf95ed692019-11-13 04:53:15139 bool driver = false;
140 bool driverUponly = false;
141 bool driverWdm = false;
Rui Ueyama136d27a2019-07-11 05:40:30142 bool showTiming = false;
143 bool showSummary = false;
Tobias Hieta33f93422023-07-12 07:22:06144 bool printSearchPaths = false;
Rui Ueyama136d27a2019-07-11 05:40:30145 unsigned debugTypes = static_cast<unsigned>(DebugType::None);
Nico Weber67d311a2022-11-14 19:23:56146 llvm::SmallVector<llvm::StringRef, 0> mllvmOpts;
Rui Ueyama136d27a2019-07-11 05:40:30147 std::vector<std::string> natvisFiles;
Eric Astora39b14f2020-04-07 20:16:22148 llvm::StringMap<std::string> namedStreams;
Rui Ueyama136d27a2019-07-11 05:40:30149 llvm::SmallString<128> pdbAltPath;
Nico Weberf964ca82021-10-30 15:22:55150 int pdbPageSize = 4096;
Rui Ueyama136d27a2019-07-11 05:40:30151 llvm::SmallString<128> pdbPath;
152 llvm::SmallString<128> pdbSourcePath;
153 std::vector<llvm::StringRef> argv;
Rui Ueyamaeb262ce2015-06-04 02:12:16154
155 // Symbols in this set are considered as live by the garbage collector.
Rui Ueyama332fc7122019-07-12 06:12:27156 std::vector<Symbol *> gcroot;
Rui Ueyamab41b7e52015-05-29 16:21:11157
Rui Ueyama136d27a2019-07-11 05:40:30158 std::set<std::string> noDefaultLibs;
159 bool noDefaultLibAll = false;
Rui Ueyamad21b00b2015-05-31 19:17:14160
Rui Ueyama97dff9e2015-06-17 00:16:33161 // True if we are creating a DLL.
Rui Ueyama136d27a2019-07-11 05:40:30162 bool dll = false;
163 StringRef implib;
Tobias Hietaeb4eef92022-04-12 14:06:46164 bool noimplib = false;
Rui Ueyama136d27a2019-07-11 05:40:30165 std::set<std::string> delayLoads;
166 std::map<std::string, int> dllOrder;
Jacek Caban99a23542024-09-11 12:46:40167 Symbol *arm64ECIcallHelper = nullptr;
Rui Ueyama97dff9e2015-06-17 00:16:33168
Miguel A. Arroyo5cd6e212024-11-12 20:30:48169 llvm::DenseSet<llvm::StringRef> saveTempsArgs;
Bob Haarman69b196d2017-02-08 18:36:41170
Reid Kleckneraf2f7da2018-02-06 01:58:26171 // /guard:cf
Pengfei Wang184377d2021-04-14 06:21:52172 int guardCF = GuardCFLevel::Off;
Reid Kleckneraf2f7da2018-02-06 01:58:26173
Rui Ueyamacd3f99b2015-07-24 23:51:14174 // Used for SafeSEH.
Reid Klecknerfe44a532019-07-16 18:17:33175 bool safeSEH = false;
Rui Ueyama136d27a2019-07-11 05:40:30176 Symbol *sehTable = nullptr;
177 Symbol *sehCount = nullptr;
Martin Storsjö745eb022020-07-27 20:44:41178 bool noSEH = false;
Rui Ueyamacd3f99b2015-07-24 23:51:14179
Peter Collingbourne526ff152015-08-14 04:47:07180 // Used for /opt:lldlto=N
Rui Ueyama136d27a2019-07-11 05:40:30181 unsigned ltoo = 2;
Scott Linder45ee0a92023-02-15 17:12:47182 // Used for /opt:lldltocgo=N
183 std::optional<unsigned> ltoCgo;
Peter Collingbourne526ff152015-08-14 04:47:07184
Peter Collingbournedf5783b2015-08-28 22:16:09185 // Used for /opt:lldltojobs=N
Alexandre Ganea09158252020-03-27 14:20:39186 std::string thinLTOJobs;
Bob Haarmancde5e5b2017-02-02 23:58:14187 // Used for /opt:lldltopartitions=N
Rui Ueyama136d27a2019-07-11 05:40:30188 unsigned ltoPartitions = 1;
Peter Collingbournedf5783b2015-08-28 22:16:09189
Martin Storsjö7a05c092024-01-04 14:03:21190 // Used for /lldltocache=path
Rui Ueyama136d27a2019-07-11 05:40:30191 StringRef ltoCache;
Martin Storsjö7a05c092024-01-04 14:03:21192 // Used for /lldltocachepolicy=policy
Rui Ueyama136d27a2019-07-11 05:40:30193 llvm::CachePruningPolicy ltoCachePolicy;
Peter Collingbourne052e855e2017-09-08 00:50:50194
rojamdb79e9902020-11-05 19:41:35195 // Used for /opt:[no]ltodebugpassmanager
196 bool ltoDebugPassManager = false;
197
Rui Ueyama6600eb12015-07-04 23:37:32198 // Used for /merge:from=to (e.g. /merge:.rdata=.text)
Rui Ueyama136d27a2019-07-11 05:40:30199 std::map<StringRef, StringRef> merge;
Rui Ueyama6600eb12015-07-04 23:37:32200
Rui Ueyama440138c2016-06-20 03:39:39201 // Used for /section=.name,{DEKPRSW} to set section attributes.
Rui Ueyama136d27a2019-07-11 05:40:30202 std::map<StringRef, uint32_t> section;
Rui Ueyama440138c2016-06-20 03:39:39203
Rui Ueyama24c5fd02015-06-18 00:12:42204 // Options for manifest files.
Nico Weber400a1de2021-08-24 14:19:21205 ManifestKind manifest = Default;
Rui Ueyama136d27a2019-07-11 05:40:30206 int manifestID = 1;
Nico Weber400a1de2021-08-24 14:19:21207 llvm::SetVector<StringRef> manifestDependencies;
Rui Ueyama136d27a2019-07-11 05:40:30208 bool manifestUAC = true;
209 std::vector<std::string> manifestInput;
210 StringRef manifestLevel = "'asInvoker'";
211 StringRef manifestUIAccess = "'false'";
212 StringRef manifestFile;
Rui Ueyama24c5fd02015-06-18 00:12:42213
Haohai Wen2a631a82023-07-01 00:58:56214 // used for /dwodir
215 StringRef dwoDir;
216
Rui Ueyama2edb35a2015-06-18 19:09:30217 // Used for /failifmismatch.
Rui Ueyama136d27a2019-07-11 05:40:30218 std::map<StringRef, std::pair<StringRef, InputFile *>> mustMatch;
Rui Ueyama8854d8a2015-06-04 19:21:24219
Rui Ueyama57175aa2018-01-27 00:34:46220 // Used for /order.
Rui Ueyama136d27a2019-07-11 05:40:30221 llvm::StringMap<int> order;
Rui Ueyama57175aa2018-01-27 00:34:46222
Peter Collingbourne6f24fdb2017-01-14 03:14:46223 // Used for /lldmap.
Sylvain Audib91905a2020-03-23 21:06:48224 std::string lldmapFile;
225
226 // Used for /map.
Rui Ueyama136d27a2019-07-11 05:40:30227 std::string mapFile;
Peter Collingbourne6f24fdb2017-01-14 03:14:46228
Pengxuan Zheng7b317562022-09-20 00:21:21229 // Used for /mapinfo.
230 bool mapInfo = false;
231
Bob Haarman63efb282019-07-11 18:03:14232 // Used for /thinlto-index-only:
233 llvm::StringRef thinLTOIndexOnlyArg;
234
Ivan Tadeu Ferreira Antunes Filho73fd9d32023-04-04 16:57:53235 // Used for /thinlto-prefix-replace:
236 // Replace the prefix in paths generated for ThinLTO, replacing
237 // thinLTOPrefixReplaceOld with thinLTOPrefixReplaceNew. If
238 // thinLTOPrefixReplaceNativeObject is defined, replace the prefix of object
239 // file paths written to the response file given in the
240 // --thinlto-index-only=${response} option with
241 // thinLTOPrefixReplaceNativeObject, instead of thinLTOPrefixReplaceNew.
242 llvm::StringRef thinLTOPrefixReplaceOld;
243 llvm::StringRef thinLTOPrefixReplaceNew;
244 llvm::StringRef thinLTOPrefixReplaceNativeObject;
Bob Haarman5011b832019-07-11 18:48:58245
246 // Used for /thinlto-object-suffix-replace:
247 std::pair<llvm::StringRef, llvm::StringRef> thinLTOObjectSuffixReplace;
248
Bob Haarman5375b942019-08-21 18:24:59249 // Used for /lto-obj-path:
250 llvm::StringRef ltoObjPath;
251
Yolanda Chen4f9c61e2021-03-25 02:55:18252 // Used for /lto-cs-profile-generate:
253 bool ltoCSProfileGenerate = false;
254
255 // Used for /lto-cs-profile-path
256 llvm::StringRef ltoCSProfileFile;
257
Yolanda Chen8fa16cc2021-08-11 16:45:55258 // Used for /lto-pgo-warn-mismatch:
259 bool ltoPGOWarnMismatch = true;
260
chrulski-intela9fe23c2024-03-20 15:02:43261 // Used for /lto-sample-profile:
262 llvm::StringRef ltoSampleProfileName;
263
Zequan Wu763671f2020-07-21 20:46:11264 // Used for /call-graph-ordering-file:
265 llvm::MapVector<std::pair<const SectionChunk *, const SectionChunk *>,
266 uint64_t>
267 callGraphProfile;
268 bool callGraphProfileSort = false;
269
270 // Used for /print-symbol-order:
271 StringRef printSymbolOrder;
272
Alex Brachetfd9962e2022-07-11 21:31:01273 // Used for /vfsoverlay:
274 std::unique_ptr<llvm::vfs::FileSystem> vfs;
275
Rui Ueyamae6a33e12019-08-07 10:16:21276 uint64_t align = 4096;
Rui Ueyama136d27a2019-07-11 05:40:30277 uint64_t imageBase = -1;
278 uint64_t fileAlign = 512;
279 uint64_t stackReserve = 1024 * 1024;
280 uint64_t stackCommit = 4096;
281 uint64_t heapReserve = 1024 * 1024;
282 uint64_t heapCommit = 4096;
283 uint32_t majorImageVersion = 0;
284 uint32_t minorImageVersion = 0;
Martin Storsjöbc8f3b42020-10-04 08:52:36285 // If changing the default os/subsys version here, update the default in
286 // the MinGW driver accordingly.
Rui Ueyama136d27a2019-07-11 05:40:30287 uint32_t majorOSVersion = 6;
288 uint32_t minorOSVersion = 0;
Martin Storsjö45c4c542020-10-03 22:29:45289 uint32_t majorSubsystemVersion = 6;
290 uint32_t minorSubsystemVersion = 0;
Rui Ueyama136d27a2019-07-11 05:40:30291 uint32_t timestamp = 0;
292 uint32_t functionPadMin = 0;
Alexandre Ganea356139b2023-10-06 02:33:58293 uint32_t timeTraceGranularity = 0;
Aleksei Nurmukhametov76947e02023-11-08 20:21:05294 uint16_t dependentLoadFlags = 0;
Rui Ueyama136d27a2019-07-11 05:40:30295 bool dynamicBase = true;
296 bool allowBind = true;
Rui Ueyamaa2923b22020-03-13 10:41:18297 bool cetCompat = false;
Rui Ueyama136d27a2019-07-11 05:40:30298 bool nxCompat = true;
299 bool allowIsolation = true;
300 bool terminalServerAware = true;
301 bool largeAddressAware = false;
302 bool highEntropyVA = false;
303 bool appContainer = false;
304 bool mingw = false;
305 bool warnMissingOrderSymbol = true;
306 bool warnLocallyDefinedImported = true;
307 bool warnDebugInfoUnusable = true;
Reid Klecknerdeaf1212019-10-29 22:57:40308 bool warnLongSectionNames = true;
Martin Storsjöce211c52021-06-17 18:51:37309 bool warnStdcallFixup = true;
Rui Ueyama136d27a2019-07-11 05:40:30310 bool incremental = true;
311 bool integrityCheck = false;
312 bool killAt = false;
313 bool repro = false;
314 bool swaprunCD = false;
315 bool swaprunNet = false;
Bob Haarman63efb282019-07-11 18:03:14316 bool thinLTOEmitImportsFiles;
317 bool thinLTOIndexOnly;
Alexandre Ganea356139b2023-10-06 02:33:58318 bool timeTraceEnabled = false;
Martin Storsjö7f0e6c32020-04-25 21:49:44319 bool autoImport = false;
320 bool pseudoRelocs = false;
Martin Storsjöce211c52021-06-17 18:51:37321 bool stdcallFixup = false;
Qfrost3f558532023-01-02 09:20:15322 bool writeCheckSum = false;
Matheus Izvekov3923e612023-10-02 20:54:43323 EmitKind emit = EmitKind::Obj;
Martin Storsjöa67ae8c2023-10-20 20:44:44324 bool allowDuplicateWeak = false;
Zequan Wuaaf3a8d2023-12-05 19:57:45325 BuildIDHash buildIDHash = BuildIDHash::None;
Rui Ueyama411c63602015-05-28 19:09:30326};
327
Fangrui Song982575fd2024-12-04 04:51:50328struct COFFSyncStream : SyncStream {
329 COFFLinkerContext &ctx;
330 COFFSyncStream(COFFLinkerContext &ctx, DiagLevel level);
331};
332
333template <typename T>
334std::enable_if_t<!std::is_pointer_v<std::remove_reference_t<T>>,
335 const COFFSyncStream &>
336operator<<(const COFFSyncStream &s, T &&v) {
337 s.os << std::forward<T>(v);
338 return s;
339}
340
341inline const COFFSyncStream &operator<<(const COFFSyncStream &s,
342 const char *v) {
343 s.os << v;
344 return s;
345}
346
347inline const COFFSyncStream &operator<<(const COFFSyncStream &s, Error v) {
348 s.os << llvm::toString(std::move(v));
349 return s;
350}
351
352// Report a log if -verbose is specified.
353COFFSyncStream Log(COFFLinkerContext &ctx);
354
355// Print a message to stdout.
356COFFSyncStream Msg(COFFLinkerContext &ctx);
357
358// Report a warning. Upgraded to an error if /WX is specified.
359COFFSyncStream Warn(COFFLinkerContext &ctx);
360
361// Report an error that will suppress the output file generation.
362COFFSyncStream Err(COFFLinkerContext &ctx);
363
364// Report a fatal error that exits immediately. This should generally be avoided
365// in favor of Err.
366COFFSyncStream Fatal(COFFLinkerContext &ctx);
367
368uint64_t errCount(COFFLinkerContext &ctx);
369
Nico Weber7c266412022-08-08 15:32:26370} // namespace lld::coff
Rui Ueyama411c63602015-05-28 19:09:30371
372#endif