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