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_WASM_CONFIG_H
10#define LLD_WASM_CONFIG_H
11
12#include "llvm/ADT/SmallVector.h"
13#include "llvm/ADT/StringRef.h"
14#include "llvm/ADT/StringSet.h"
15#include "llvm/ADT/Twine.h"
16#include "llvm/BinaryFormat/Wasm.h"
17#include "llvm/Support/CachePruning.h"
18#include <optional>
19
20namespace llvm {
21enum class CodeGenOptLevel;
22} // namespace llvm
23
24namespace lld::wasm {
25
26class InputFile;
27class StubFile;
28class ObjFile;
29class SharedFile;
30class BitcodeFile;
31class InputTable;
32class InputGlobal;
33class InputFunction;
34class Symbol;
35class DefinedData;
36class GlobalSymbol;
37class DefinedFunction;
38class UndefinedFunction;
39class DefinedGlobal;
40class UndefinedGlobal;
41class TableSymbol;
42
43// For --unresolved-symbols.
44enum class UnresolvedPolicy { ReportError, Warn, Ignore, ImportDynamic };
45
46// For --build-id.
47enum class BuildIdKind { None, Fast, Sha1, Hexstring, Uuid };
48
49// This struct contains the global configuration for the linker.
50// Most fields are direct mapping from the command line options
51// and such fields have the same name as the corresponding options.
52// Most fields are initialized by the driver.
53struct Config {
54 bool allowMultipleDefinition;
55 bool bsymbolic;
56 bool checkFeatures;
57 bool compressRelocations;
58 bool demangle;
59 bool disableVerify;
60 bool emitRelocs;
61 bool exportAll;
62 bool exportDynamic;
63 bool exportTable;
64 bool extendedConst;
65 bool growableTable;
66 bool gcSections;
67 llvm::StringSet<> keepSections;
68 bool cooperativeThreading;
69 bool libcallThreadContext;
70 std::optional<std::pair<llvm::StringRef, llvm::StringRef>> memoryImport;
71 std::optional<llvm::StringRef> memoryExport;
72 bool sharedMemory;
73 bool importTable;
74 bool importUndefined;
75 std::optional<bool> is64;
76 bool mergeDataSegments;
77 bool noinhibitExec;
78 bool pie;
79 bool printGcSections;
80 bool relocatable;
81 bool saveTemps;
82 bool shared;
83 bool shlibSigCheck;
84 bool stripAll;
85 bool stripDebug;
86 bool stackFirst;
87 // Static linking is currently the default under WebAssembly. This may
88 // change as some point in the future if dynamic linking becomes more widely
89 // used.
90 bool isStatic = true;
91 bool thinLTOEmitImportsFiles;
92 bool thinLTOEmitIndexFiles;
93 bool thinLTOIndexOnly;
94 bool trace;
95 uint64_t globalBase;
96 uint64_t initialHeap;
97 uint64_t initialMemory;
98 uint64_t maxMemory;
99 bool noGrowableMemory;
100 // The table offset at which to place function addresses. We reserve zero
101 // for the null function pointer. This gets set to 1 for executables and 0
102 // for shared libraries (since they always added to a dynamic offset at
103 // runtime).
104 uint64_t tableBase;
105 uint64_t zStackSize;
106 uint64_t pageSize;
107 unsigned ltoPartitions;
108 unsigned ltoo;
109 llvm::CodeGenOptLevel ltoCgo;
110 unsigned optimize;
111 bool ltoDebugPassManager;
112 UnresolvedPolicy unresolvedSymbols;
113 BuildIdKind buildId = BuildIdKind::None;
114
115 llvm::StringRef entry;
116 llvm::StringRef ltoObjPath;
117 llvm::StringRef mapFile;
118 llvm::StringRef outputFile;
119 llvm::StringRef soName;
120 llvm::StringRef thinLTOCacheDir;
121 llvm::StringRef thinLTOJobs;
122 llvm::StringRef thinLTOIndexOnlyArg;
123 std::pair<llvm::StringRef, llvm::StringRef> thinLTOObjectSuffixReplace;
124 llvm::StringRef thinLTOPrefixReplaceOld;
125 llvm::StringRef thinLTOPrefixReplaceNew;
126 llvm::StringRef thinLTOPrefixReplaceNativeObject;
127 llvm::StringRef whyExtract;
128
129 llvm::StringSet<> allowUndefinedSymbols;
130 llvm::StringSet<> exportedSymbols;
131 std::vector<llvm::StringRef> requiredExports;
132 llvm::SmallVector<llvm::StringRef, 0> searchPaths;
133 llvm::SmallVector<llvm::StringRef, 0> rpath;
134 llvm::CachePruningPolicy thinLTOCachePolicy;
135 std::optional<std::vector<std::string>> features;
136 std::optional<std::vector<std::string>> extraFeatures;
137 llvm::SmallVector<uint8_t, 0> buildIdVector;
138
139 bool isMultithreaded() const { return sharedMemory || cooperativeThreading; }
140};
141
142// The Ctx object hold all other (non-configuration) global state.
143struct Ctx {
144 Config arg;
145
146 llvm::SmallVector<ObjFile *, 0> objectFiles;
147 llvm::SmallVector<StubFile *, 0> stubFiles;
148 llvm::SmallVector<SharedFile *, 0> sharedFiles;
149 llvm::SmallVector<BitcodeFile *, 0> bitcodeFiles;
150 llvm::SmallVector<BitcodeFile *, 0> lazyBitcodeFiles;
151 llvm::SmallVector<InputFunction *, 0> syntheticFunctions;
152 llvm::SmallVector<InputGlobal *, 0> syntheticGlobals;
153 llvm::SmallVector<InputTable *, 0> syntheticTables;
154
155 // linker-generated symbols
156 struct WasmSym {
157 // __global_base
158 // Symbol marking the start of the global section.
159 DefinedData *globalBase;
160
161 // __stack_pointer/__stack_low/__stack_high
162 // Global that holds current value of stack pointer and data symbols marking
163 // the start and end of the stack region. stackPointer is initialized to
164 // stackHigh and grows downwards towards stackLow
165 GlobalSymbol *stackPointer;
166 DefinedData *stackLow;
167 DefinedData *stackHigh;
168
169 // __tls_base
170 // Global that holds the address of the base of the current thread's
171 // TLS block.
172 DefinedGlobal *tlsBase;
173
174 // __tls_size
175 // Symbol whose value is the size of the TLS block.
176 DefinedGlobal *tlsSize;
177
178 // __tls_align
179 // Symbol whose value is the alignment of the TLS block.
180 DefinedGlobal *tlsAlign;
181
182 // __rodata_start/__rodata_end
183 // Symbols marking the start/end of readonly data
184 DefinedData *rodataStart;
185 DefinedData *rodataEnd;
186
187 // __data_end
188 // Symbol marking the end of the data and bss.
189 DefinedData *dataEnd;
190
191 // __heap_base/__heap_end
192 // Symbols marking the beginning and end of the "heap". It starts at the end
193 // of the data, bss and explicit stack, and extends to the end of the linear
194 // memory allocated by wasm-ld. This region of memory is not used by the
195 // linked code, so it may be used as a backing store for `sbrk` or `malloc`
196 // implementations.
197 DefinedData *heapBase;
198 DefinedData *heapEnd;
199
200 // __wasm_first_page_end
201 // A symbol whose address is the end of the first page in memory (if any).
202 DefinedData *firstPageEnd;
203
204 // __wasm_init_memory_flag
205 // Symbol whose contents are nonzero iff memory has already been
206 // initialized.
207 DefinedData *initMemoryFlag;
208
209 // __wasm_init_memory
210 // Function that initializes passive data segments during instantiation.
211 DefinedFunction *initMemory;
212
213 // __wasm_call_ctors
214 // Function that directly calls all ctors in priority order.
215 DefinedFunction *callCtors;
216
217 // __wasm_call_dtors
218 // Function that calls the libc/etc. cleanup function.
219 DefinedFunction *callDtors;
220
221 // __wasm_apply_global_relocs
222 // Function that applies relocations to wasm globals post-instantiation.
223 // Unlike __wasm_apply_data_relocs this needs to run on every thread.
224 DefinedFunction *applyGlobalRelocs;
225
226 // __wasm_apply_tls_relocs
227 // Like __wasm_apply_data_relocs but for TLS section. These must be
228 // delayed until __wasm_init_tls.
229 DefinedFunction *applyTLSRelocs;
230
231 // __wasm_apply_global_tls_relocs
232 // Like applyGlobalRelocs but for globals that hold TLS addresses. These
233 // must be delayed until __wasm_init_tls.
234 DefinedFunction *applyGlobalTLSRelocs;
235
236 // __wasm_init_tls
237 // Function that allocates thread-local storage and initializes it.
238 DefinedFunction *initTLS;
239
240 // Pointer to the function that is to be used in the start section.
241 // (normally an alias of initMemory, or applyGlobalRelocs).
242 DefinedFunction *startFunction;
243
244 // __dso_handle
245 // Symbol used in calls to __cxa_atexit to determine current DLL
246 DefinedData *dsoHandle;
247
248 // __table_base
249 // Used in PIC code for offset of indirect function table
250 GlobalSymbol *tableBase;
251
252 // __memory_base
253 // Used in PIC code for offset of global data
254 GlobalSymbol *memoryBase;
255
256 // __indirect_function_table
257 // Used as an address space for function pointers, with each function that
258 // is used as a function pointer being allocated a slot.
259 TableSymbol *indirectFunctionTable;
260
261 // __wasm_set_tls_base
262 // Function used to set TLS base in libcall thread context modules.
263 UndefinedFunction *setTLSBase;
264
265 // __wasm_get_tls_base
266 // Function used to get TLS base in libcall thread context modules.
267 UndefinedFunction *getTLSBase;
268 };
269 WasmSym sym;
270
271 // True if we are creating position-independent code.
272 bool isPic = false;
273
274 // True if we have an MVP input that uses __indirect_function_table and which
275 // requires it to be allocated to table number 0.
276 bool legacyFunctionTable = false;
277
278 // Will be set to true if bss data segments should be emitted. In most cases
279 // this is not necessary.
280 bool emitBssSegments = false;
281
282 // A tuple of (reference, extractedFile, sym). Used by --why-extract=.
283 llvm::SmallVector<std::tuple<std::string, const InputFile *, const Symbol &>,
284 0>
285 whyExtractRecords;
286
287 Ctx();
288 void reset();
289};
290
291extern Ctx ctx;
292
293void errorOrWarn(const llvm::Twine &msg);
294
295} // namespace lld::wasm
296
297#endif
298