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
*addSharedFunction(StringRef name
, uint32_t flags
, InputFile
*file
,
54 const WasmSignature
*sig
);
55 Symbol
*addSharedData(StringRef name
, uint32_t flags
, InputFile
*file
);
56 Symbol
*addDefinedFunction(StringRef name
, uint32_t flags
, InputFile
*file
,
57 InputFunction
*function
);
58 Symbol
*addDefinedData(StringRef name
, uint32_t flags
, InputFile
*file
,
59 InputChunk
*segment
, uint64_t address
, uint64_t size
);
60 Symbol
*addDefinedGlobal(StringRef name
, uint32_t flags
, InputFile
*file
,
62 Symbol
*addDefinedTag(StringRef name
, uint32_t flags
, InputFile
*file
,
64 Symbol
*addDefinedTable(StringRef name
, uint32_t flags
, InputFile
*file
,
67 Symbol
*addUndefinedFunction(StringRef name
,
68 std::optional
<StringRef
> importName
,
69 std::optional
<StringRef
> importModule
,
70 uint32_t flags
, InputFile
*file
,
71 const WasmSignature
*signature
,
72 bool isCalledDirectly
);
73 Symbol
*addUndefinedData(StringRef name
, uint32_t flags
, InputFile
*file
);
74 Symbol
*addUndefinedGlobal(StringRef name
,
75 std::optional
<StringRef
> importName
,
76 std::optional
<StringRef
> importModule
,
77 uint32_t flags
, InputFile
*file
,
78 const WasmGlobalType
*type
);
79 Symbol
*addUndefinedTable(StringRef name
, std::optional
<StringRef
> importName
,
80 std::optional
<StringRef
> importModule
,
81 uint32_t flags
, InputFile
*file
,
82 const WasmTableType
*type
);
83 Symbol
*addUndefinedTag(StringRef name
, std::optional
<StringRef
> importName
,
84 std::optional
<StringRef
> importModule
, uint32_t flags
,
85 InputFile
*file
, const WasmSignature
*sig
);
87 TableSymbol
*resolveIndirectFunctionTable(bool required
);
89 void addLazy(StringRef name
, InputFile
*f
);
91 bool addComdat(StringRef name
);
93 DefinedData
*addSyntheticDataSymbol(StringRef name
, uint32_t flags
);
94 DefinedGlobal
*addSyntheticGlobal(StringRef name
, uint32_t flags
,
96 DefinedFunction
*addSyntheticFunction(StringRef name
, uint32_t flags
,
97 InputFunction
*function
);
98 DefinedData
*addOptionalDataSymbol(StringRef name
, uint64_t value
= 0);
99 DefinedGlobal
*addOptionalGlobalSymbol(StringRef name
, InputGlobal
*global
);
100 DefinedTable
*addSyntheticTable(StringRef name
, uint32_t flags
,
103 void handleSymbolVariants();
104 void handleWeakUndefines();
105 DefinedFunction
*createUndefinedStub(const WasmSignature
&sig
);
108 std::pair
<Symbol
*, bool> insert(StringRef name
, const InputFile
*file
);
109 std::pair
<Symbol
*, bool> insertName(StringRef name
);
111 bool getFunctionVariant(Symbol
* sym
, const WasmSignature
*sig
,
112 const InputFile
*file
, Symbol
**out
);
113 InputFunction
*replaceWithUnreachable(Symbol
*sym
, const WasmSignature
&sig
,
114 StringRef debugName
);
115 void replaceWithUndefined(Symbol
*sym
);
117 TableSymbol
*createDefinedIndirectFunctionTable(StringRef name
);
118 TableSymbol
*createUndefinedIndirectFunctionTable(StringRef name
);
120 // Maps symbol names to index into the symVector. -1 means that symbols
121 // is to not yet in the vector but it should have tracing enabled if it is
123 llvm::DenseMap
<llvm::CachedHashStringRef
, int> symMap
;
124 std::vector
<Symbol
*> symVector
;
126 // For certain symbols types, e.g. function symbols, we allow for multiple
127 // variants of the same symbol with different signatures.
128 llvm::DenseMap
<llvm::CachedHashStringRef
, std::vector
<Symbol
*>> symVariants
;
129 llvm::DenseMap
<WasmSignature
, DefinedFunction
*> stubFunctions
;
131 // Comdat groups define "link once" sections. If two comdat groups have the
132 // same name, only one of them is linked, and the other is ignored. This set
133 // is used to uniquify them.
134 llvm::DenseSet
<llvm::CachedHashStringRef
> comdatGroups
;
137 std::unique_ptr
<BitcodeCompiler
> lto
;
140 extern SymbolTable
*symtab
;
142 } // namespace lld::wasm