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