1ece8a530Spatrick //===- SymbolTable.h --------------------------------------------*- C++ -*-===// 2ece8a530Spatrick // 3ece8a530Spatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4ece8a530Spatrick // See https://llvm.org/LICENSE.txt for license information. 5ece8a530Spatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6ece8a530Spatrick // 7ece8a530Spatrick //===----------------------------------------------------------------------===// 8ece8a530Spatrick 9ece8a530Spatrick #ifndef LLD_WASM_SYMBOL_TABLE_H 10ece8a530Spatrick #define LLD_WASM_SYMBOL_TABLE_H 11ece8a530Spatrick 12ece8a530Spatrick #include "InputFiles.h" 13ece8a530Spatrick #include "LTO.h" 14ece8a530Spatrick #include "Symbols.h" 15ece8a530Spatrick #include "lld/Common/LLVM.h" 16ece8a530Spatrick #include "llvm/ADT/CachedHashString.h" 17ece8a530Spatrick #include "llvm/ADT/DenseSet.h" 181cf9926bSpatrick #include "llvm/BinaryFormat/WasmTraits.h" 19*dfe94b16Srobert #include <optional> 20ece8a530Spatrick 21ece8a530Spatrick namespace lld { 22ece8a530Spatrick namespace wasm { 23ece8a530Spatrick 24ece8a530Spatrick class InputSegment; 25ece8a530Spatrick 26ece8a530Spatrick // SymbolTable is a bucket of all known symbols, including defined, 27ece8a530Spatrick // undefined, or lazy symbols (the last one is symbols in archive 28ece8a530Spatrick // files whose archive members are not yet loaded). 29ece8a530Spatrick // 30ece8a530Spatrick // We put all symbols of all files to a SymbolTable, and the 31ece8a530Spatrick // SymbolTable selects the "best" symbols if there are name 32ece8a530Spatrick // conflicts. For example, obviously, a defined symbol is better than 33ece8a530Spatrick // an undefined symbol. Or, if there's a conflict between a lazy and a 34ece8a530Spatrick // undefined, it'll read an archive member to read a real definition 35ece8a530Spatrick // to replace the lazy symbol. The logic is implemented in the 36ece8a530Spatrick // add*() functions, which are called by input files as they are parsed. 37ece8a530Spatrick // There is one add* function per symbol type. 38ece8a530Spatrick class SymbolTable { 39ece8a530Spatrick public: symbols()40*dfe94b16Srobert ArrayRef<Symbol *> symbols() const { return symVector; } 41*dfe94b16Srobert 42ece8a530Spatrick void wrap(Symbol *sym, Symbol *real, Symbol *wrap); 43ece8a530Spatrick 44ece8a530Spatrick void addFile(InputFile *file); 45ece8a530Spatrick 46*dfe94b16Srobert void compileBitcodeFiles(); 47ece8a530Spatrick 48ece8a530Spatrick Symbol *find(StringRef name); 49ece8a530Spatrick 50ece8a530Spatrick void replace(StringRef name, Symbol* sym); 51ece8a530Spatrick 52ece8a530Spatrick void trace(StringRef name); 53ece8a530Spatrick 54ece8a530Spatrick Symbol *addDefinedFunction(StringRef name, uint32_t flags, InputFile *file, 55ece8a530Spatrick InputFunction *function); 56ece8a530Spatrick Symbol *addDefinedData(StringRef name, uint32_t flags, InputFile *file, 571cf9926bSpatrick InputChunk *segment, uint64_t address, uint64_t size); 58ece8a530Spatrick Symbol *addDefinedGlobal(StringRef name, uint32_t flags, InputFile *file, 59ece8a530Spatrick InputGlobal *g); 601cf9926bSpatrick Symbol *addDefinedTag(StringRef name, uint32_t flags, InputFile *file, 611cf9926bSpatrick InputTag *t); 621cf9926bSpatrick Symbol *addDefinedTable(StringRef name, uint32_t flags, InputFile *file, 631cf9926bSpatrick InputTable *t); 64ece8a530Spatrick 65bb684c34Spatrick Symbol *addUndefinedFunction(StringRef name, 66*dfe94b16Srobert std::optional<StringRef> importName, 67*dfe94b16Srobert std::optional<StringRef> importModule, 68bb684c34Spatrick uint32_t flags, InputFile *file, 69bb684c34Spatrick const WasmSignature *signature, 70ece8a530Spatrick bool isCalledDirectly); 71ece8a530Spatrick Symbol *addUndefinedData(StringRef name, uint32_t flags, InputFile *file); 72bb684c34Spatrick Symbol *addUndefinedGlobal(StringRef name, 73*dfe94b16Srobert std::optional<StringRef> importName, 74*dfe94b16Srobert std::optional<StringRef> importModule, 75bb684c34Spatrick uint32_t flags, InputFile *file, 76bb684c34Spatrick const WasmGlobalType *type); 77*dfe94b16Srobert Symbol *addUndefinedTable(StringRef name, std::optional<StringRef> importName, 78*dfe94b16Srobert std::optional<StringRef> importModule, 791cf9926bSpatrick uint32_t flags, InputFile *file, 801cf9926bSpatrick const WasmTableType *type); 81*dfe94b16Srobert Symbol *addUndefinedTag(StringRef name, std::optional<StringRef> importName, 82*dfe94b16Srobert std::optional<StringRef> importModule, uint32_t flags, 83*dfe94b16Srobert InputFile *file, const WasmSignature *sig); 841cf9926bSpatrick 851cf9926bSpatrick TableSymbol *resolveIndirectFunctionTable(bool required); 86ece8a530Spatrick 87ece8a530Spatrick void addLazy(ArchiveFile *f, const llvm::object::Archive::Symbol *sym); 88ece8a530Spatrick 89ece8a530Spatrick bool addComdat(StringRef name); 90ece8a530Spatrick 91ece8a530Spatrick DefinedData *addSyntheticDataSymbol(StringRef name, uint32_t flags); 92ece8a530Spatrick DefinedGlobal *addSyntheticGlobal(StringRef name, uint32_t flags, 93ece8a530Spatrick InputGlobal *global); 94ece8a530Spatrick DefinedFunction *addSyntheticFunction(StringRef name, uint32_t flags, 95ece8a530Spatrick InputFunction *function); 961cf9926bSpatrick DefinedData *addOptionalDataSymbol(StringRef name, uint64_t value = 0); 971cf9926bSpatrick DefinedGlobal *addOptionalGlobalSymbol(StringRef name, InputGlobal *global); 981cf9926bSpatrick DefinedTable *addSyntheticTable(StringRef name, uint32_t flags, 991cf9926bSpatrick InputTable *global); 100ece8a530Spatrick 101ece8a530Spatrick void handleSymbolVariants(); 102ece8a530Spatrick void handleWeakUndefines(); 1031cf9926bSpatrick DefinedFunction *createUndefinedStub(const WasmSignature &sig); 104ece8a530Spatrick 105ece8a530Spatrick std::vector<ObjFile *> objectFiles; 106*dfe94b16Srobert std::vector<StubFile *> stubFiles; 107ece8a530Spatrick std::vector<SharedFile *> sharedFiles; 108ece8a530Spatrick std::vector<BitcodeFile *> bitcodeFiles; 109ece8a530Spatrick std::vector<InputFunction *> syntheticFunctions; 110ece8a530Spatrick std::vector<InputGlobal *> syntheticGlobals; 1111cf9926bSpatrick std::vector<InputTable *> syntheticTables; 112ece8a530Spatrick 113ece8a530Spatrick private: 114ece8a530Spatrick std::pair<Symbol *, bool> insert(StringRef name, const InputFile *file); 115ece8a530Spatrick std::pair<Symbol *, bool> insertName(StringRef name); 116ece8a530Spatrick 117ece8a530Spatrick bool getFunctionVariant(Symbol* sym, const WasmSignature *sig, 118ece8a530Spatrick const InputFile *file, Symbol **out); 119ece8a530Spatrick InputFunction *replaceWithUnreachable(Symbol *sym, const WasmSignature &sig, 120ece8a530Spatrick StringRef debugName); 1211cf9926bSpatrick void replaceWithUndefined(Symbol *sym); 1221cf9926bSpatrick 1231cf9926bSpatrick TableSymbol *createDefinedIndirectFunctionTable(StringRef name); 1241cf9926bSpatrick TableSymbol *createUndefinedIndirectFunctionTable(StringRef name); 125ece8a530Spatrick 126ece8a530Spatrick // Maps symbol names to index into the symVector. -1 means that symbols 127ece8a530Spatrick // is to not yet in the vector but it should have tracing enabled if it is 128ece8a530Spatrick // ever added. 129ece8a530Spatrick llvm::DenseMap<llvm::CachedHashStringRef, int> symMap; 130ece8a530Spatrick std::vector<Symbol *> symVector; 131ece8a530Spatrick 132bb684c34Spatrick // For certain symbols types, e.g. function symbols, we allow for multiple 133ece8a530Spatrick // variants of the same symbol with different signatures. 134ece8a530Spatrick llvm::DenseMap<llvm::CachedHashStringRef, std::vector<Symbol *>> symVariants; 1351cf9926bSpatrick llvm::DenseMap<WasmSignature, DefinedFunction *> stubFunctions; 136ece8a530Spatrick 137ece8a530Spatrick // Comdat groups define "link once" sections. If two comdat groups have the 138ece8a530Spatrick // same name, only one of them is linked, and the other is ignored. This set 139ece8a530Spatrick // is used to uniquify them. 140ece8a530Spatrick llvm::DenseSet<llvm::CachedHashStringRef> comdatGroups; 141ece8a530Spatrick 142ece8a530Spatrick // For LTO. 143ece8a530Spatrick std::unique_ptr<BitcodeCompiler> lto; 144ece8a530Spatrick }; 145ece8a530Spatrick 146ece8a530Spatrick extern SymbolTable *symtab; 147ece8a530Spatrick 148ece8a530Spatrick } // namespace wasm 149ece8a530Spatrick } // namespace lld 150ece8a530Spatrick 151ece8a530Spatrick #endif 152