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