297 lines · c
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-exception6//7//===----------------------------------------------------------------------===//8 9#ifndef LLD_WASM_CONFIG_H10#define LLD_WASM_CONFIG_H11 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/GlobPattern.h"19#include <optional>20 21namespace llvm {22enum class CodeGenOptLevel;23} // namespace llvm24 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 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 options50// 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 to86 // static linking87 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 zero98 // for the null function pointer. This gets set to 1 for executables and 099 // for shared libraries (since they always added to a dynamic offset at100 // 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 130 // --version-script export-visibility state. Wasm has no symbol versioning131 // (versions are collapsed: see the `.symver` toolchain fix), so the version132 // *tags* of a GNU version script are ignored. The meaningful part for a133 // shared module is the global:/local: export visibility: symbols matched by134 // `local:` (including `local: *;`) are hidden (not exported); symbols matched135 // by `global:` keep their default export visibility. `hasVersionScript` is136 // set iff a script was successfully parsed.137 bool hasVersionScript = false;138 bool versionGlobalAll = false; // a `global:` matched `*`139 bool versionLocalAll = false; // a `local:` matched `*`140 llvm::StringSet<> versionGlobalExact;141 llvm::StringSet<> versionLocalExact;142 llvm::SmallVector<llvm::GlobPattern, 0> versionGlobalPatterns;143 llvm::SmallVector<llvm::GlobPattern, 0> versionLocalPatterns;144 llvm::SmallVector<llvm::StringRef, 0> searchPaths;145 llvm::SmallVector<llvm::StringRef, 0> rpath;146 llvm::CachePruningPolicy thinLTOCachePolicy;147 std::optional<std::vector<std::string>> features;148 std::optional<std::vector<std::string>> extraFeatures;149 llvm::SmallVector<uint8_t, 0> buildIdVector;150};151 152// The Ctx object hold all other (non-configuration) global state.153struct Ctx {154 Config arg;155 156 llvm::SmallVector<ObjFile *, 0> objectFiles;157 llvm::SmallVector<StubFile *, 0> stubFiles;158 llvm::SmallVector<SharedFile *, 0> sharedFiles;159 llvm::SmallVector<BitcodeFile *, 0> bitcodeFiles;160 llvm::SmallVector<BitcodeFile *, 0> lazyBitcodeFiles;161 llvm::SmallVector<InputFunction *, 0> syntheticFunctions;162 llvm::SmallVector<InputGlobal *, 0> syntheticGlobals;163 llvm::SmallVector<InputTable *, 0> syntheticTables;164 165 // linker-generated symbols166 struct WasmSym {167 // __global_base168 // Symbol marking the start of the global section.169 DefinedData *globalBase;170 171 // __stack_pointer/__stack_low/__stack_high172 // Global that holds current value of stack pointer and data symbols marking173 // the start and end of the stack region. stackPointer is initialized to174 // stackHigh and grows downwards towards stackLow175 GlobalSymbol *stackPointer;176 DefinedData *stackLow;177 DefinedData *stackHigh;178 179 // __tls_base180 // Global that holds the address of the base of the current thread's181 // TLS block.182 GlobalSymbol *tlsBase;183 184 // __tls_size185 // Symbol whose value is the size of the TLS block.186 GlobalSymbol *tlsSize;187 188 // __tls_size189 // Symbol whose value is the alignment of the TLS block.190 GlobalSymbol *tlsAlign;191 192 // __data_end193 // Symbol marking the end of the data and bss.194 DefinedData *dataEnd;195 196 // __heap_base/__heap_end197 // Symbols marking the beginning and end of the "heap". It starts at the end198 // of the data, bss and explicit stack, and extends to the end of the linear199 // memory allocated by wasm-ld. This region of memory is not used by the200 // linked code, so it may be used as a backing store for `sbrk` or `malloc`201 // implementations.202 DefinedData *heapBase;203 DefinedData *heapEnd;204 205 // __wasm_first_page_end206 // A symbol whose address is the end of the first page in memory (if any).207 DefinedData *firstPageEnd;208 209 // __wasm_init_memory_flag210 // Symbol whose contents are nonzero iff memory has already been211 // initialized.212 DefinedData *initMemoryFlag;213 214 // __wasm_init_memory215 // Function that initializes passive data segments during instantiation.216 DefinedFunction *initMemory;217 218 // __wasm_call_ctors219 // Function that directly calls all ctors in priority order.220 DefinedFunction *callCtors;221 222 // __wasm_call_dtors223 // Function that calls the libc/etc. cleanup function.224 DefinedFunction *callDtors;225 226 // __wasm_apply_global_relocs227 // Function that applies relocations to wasm globals post-instantiation.228 // Unlike __wasm_apply_data_relocs this needs to run on every thread.229 DefinedFunction *applyGlobalRelocs;230 231 // __wasm_apply_tls_relocs232 // Like __wasm_apply_data_relocs but for TLS section. These must be233 // delayed until __wasm_init_tls.234 DefinedFunction *applyTLSRelocs;235 236 // __wasm_apply_global_tls_relocs237 // Like applyGlobalRelocs but for globals that hold TLS addresses. These238 // must be delayed until __wasm_init_tls.239 DefinedFunction *applyGlobalTLSRelocs;240 241 // __wasm_init_tls242 // Function that allocates thread-local storage and initializes it.243 DefinedFunction *initTLS;244 245 // Pointer to the function that is to be used in the start section.246 // (normally an alias of initMemory, or applyGlobalRelocs).247 DefinedFunction *startFunction;248 249 // __dso_handle250 // Symbol used in calls to __cxa_atexit to determine current DLL251 DefinedData *dsoHandle;252 253 // __table_base254 // Used in PIC code for offset of indirect function table255 UndefinedGlobal *tableBase;256 DefinedData *definedTableBase;257 258 // __memory_base259 // Used in PIC code for offset of global data260 UndefinedGlobal *memoryBase;261 DefinedData *definedMemoryBase;262 263 // __indirect_function_table264 // Used as an address space for function pointers, with each function that265 // is used as a function pointer being allocated a slot.266 TableSymbol *indirectFunctionTable;267 };268 WasmSym sym;269 270 // True if we are creating position-independent code.271 bool isPic = false;272 273 // True if we have an MVP input that uses __indirect_function_table and which274 // requires it to be allocated to table number 0.275 bool legacyFunctionTable = false;276 277 // Will be set to true if bss data segments should be emitted. In most cases278 // this is not necessary.279 bool emitBssSegments = false;280 281 // A tuple of (reference, extractedFile, sym). Used by --why-extract=.282 llvm::SmallVector<std::tuple<std::string, const InputFile *, const Symbol &>,283 0>284 whyExtractRecords;285 286 Ctx();287 void reset();288};289 290extern Ctx ctx;291 292void errorOrWarn(const llvm::Twine &msg);293 294} // namespace lld::wasm295 296#endif297