1 //===- SymbolTable.h --------------------------------------------*- C++ -*-===//
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
7 //===----------------------------------------------------------------------===//
9 #ifndef LLD_WASM_SYMBOL_TABLE_H
10 #define LLD_WASM_SYMBOL_TABLE_H
12 #include "InputFiles.h"
15 #include "lld/Common/LLVM.h"
16 #include "llvm/ADT/CachedHashString.h"
17 #include "llvm/ADT/DenseSet.h"
18 #include "llvm/BinaryFormat/WasmTraits.h"
25 // SymbolTable is a bucket of all known symbols, including defined,
26 // undefined, or lazy symbols (the last one is symbols in archive
27 // files whose archive members are not yet loaded).
29 // We put all symbols of all files to a SymbolTable, and the
30 // SymbolTable selects the "best" symbols if there are name
31 // conflicts. For example, obviously, a defined symbol is better than
32 // an undefined symbol. Or, if there's a conflict between a lazy and a
33 // undefined, it'll read an archive member to read a real definition
34 // to replace the lazy symbol. The logic is implemented in the
35 // add*() functions, which are called by input files as they are parsed.
36 // There is one add* function per symbol type.
39 ArrayRef
<Symbol
*> symbols() const { return symVector
; }
41 void wrap(Symbol
*sym
, Symbol
*real
, Symbol
*wrap
);
43 void addFile(InputFile
*file
, StringRef symName
= {});
45 void compileBitcodeFiles();
47 Symbol
*find(StringRef name
);
49 void replace(StringRef name
, Symbol
* sym
);
51 void trace(StringRef name
);
53 Symbol
*addDefinedFunction(StringRef name
, uint32_t flags
, InputFile
*file
,
54 InputFunction
*function
);
55 Symbol
*addDefinedData(StringRef name
, uint32_t flags
, InputFile
*file
,
56 InputChunk
*segment
, uint64_t address
, uint64_t size
);
57 Symbol
*addDefinedGlobal(StringRef name
, uint32_t flags
, InputFile
*file
,
59 Symbol
*addDefinedTag(StringRef name
, uint32_t flags
, InputFile
*file
,
61 Symbol
*addDefinedTable(StringRef name
, uint32_t flags
, InputFile
*file
,
64 Symbol
*addUndefinedFunction(StringRef name
,
65 std::optional
<StringRef
> importName
,
66 std::optional
<StringRef
> importModule
,
67 uint32_t flags
, InputFile
*file
,
68 const WasmSignature
*signature
,
69 bool isCalledDirectly
);
70 Symbol
*addUndefinedData(StringRef name
, uint32_t flags
, InputFile
*file
);
71 Symbol
*addUndefinedGlobal(StringRef name
,
72 std::optional
<StringRef
> importName
,
73 std::optional
<StringRef
> importModule
,
74 uint32_t flags
, InputFile
*file
,
75 const WasmGlobalType
*type
);
76 Symbol
*addUndefinedTable(StringRef name
, std::optional
<StringRef
> importName
,
77 std::optional
<StringRef
> importModule
,
78 uint32_t flags
, InputFile
*file
,
79 const WasmTableType
*type
);
80 Symbol
*addUndefinedTag(StringRef name
, std::optional
<StringRef
> importName
,
81 std::optional
<StringRef
> importModule
, uint32_t flags
,
82 InputFile
*file
, const WasmSignature
*sig
);
84 TableSymbol
*resolveIndirectFunctionTable(bool required
);
86 void addLazy(ArchiveFile
*f
, const llvm::object::Archive::Symbol
*sym
);
88 bool addComdat(StringRef name
);
90 DefinedData
*addSyntheticDataSymbol(StringRef name
, uint32_t flags
);
91 DefinedGlobal
*addSyntheticGlobal(StringRef name
, uint32_t flags
,
93 DefinedFunction
*addSyntheticFunction(StringRef name
, uint32_t flags
,
94 InputFunction
*function
);
95 DefinedData
*addOptionalDataSymbol(StringRef name
, uint64_t value
= 0);
96 DefinedGlobal
*addOptionalGlobalSymbol(StringRef name
, InputGlobal
*global
);
97 DefinedTable
*addSyntheticTable(StringRef name
, uint32_t flags
,
100 void handleSymbolVariants();
101 void handleWeakUndefines();
102 DefinedFunction
*createUndefinedStub(const WasmSignature
&sig
);
104 std::vector
<ObjFile
*> objectFiles
;
105 std::vector
<StubFile
*> stubFiles
;
106 std::vector
<SharedFile
*> sharedFiles
;
107 std::vector
<BitcodeFile
*> bitcodeFiles
;
108 std::vector
<InputFunction
*> syntheticFunctions
;
109 std::vector
<InputGlobal
*> syntheticGlobals
;
110 std::vector
<InputTable
*> syntheticTables
;
113 std::pair
<Symbol
*, bool> insert(StringRef name
, const InputFile
*file
);
114 std::pair
<Symbol
*, bool> insertName(StringRef name
);
116 bool getFunctionVariant(Symbol
* sym
, const WasmSignature
*sig
,
117 const InputFile
*file
, Symbol
**out
);
118 InputFunction
*replaceWithUnreachable(Symbol
*sym
, const WasmSignature
&sig
,
119 StringRef debugName
);
120 void replaceWithUndefined(Symbol
*sym
);
122 TableSymbol
*createDefinedIndirectFunctionTable(StringRef name
);
123 TableSymbol
*createUndefinedIndirectFunctionTable(StringRef name
);
125 // Maps symbol names to index into the symVector. -1 means that symbols
126 // is to not yet in the vector but it should have tracing enabled if it is
128 llvm::DenseMap
<llvm::CachedHashStringRef
, int> symMap
;
129 std::vector
<Symbol
*> symVector
;
131 // For certain symbols types, e.g. function symbols, we allow for multiple
132 // variants of the same symbol with different signatures.
133 llvm::DenseMap
<llvm::CachedHashStringRef
, std::vector
<Symbol
*>> symVariants
;
134 llvm::DenseMap
<WasmSignature
, DefinedFunction
*> stubFunctions
;
136 // Comdat groups define "link once" sections. If two comdat groups have the
137 // same name, only one of them is linked, and the other is ignored. This set
138 // is used to uniquify them.
139 llvm::DenseSet
<llvm::CachedHashStringRef
> comdatGroups
;
142 std::unique_ptr
<BitcodeCompiler
> lto
;
145 extern SymbolTable
*symtab
;
147 } // namespace lld::wasm