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/ADT/Optional.h"
19 #include "llvm/BinaryFormat/WasmTraits.h"
26 // SymbolTable is a bucket of all known symbols, including defined,
27 // undefined, or lazy symbols (the last one is symbols in archive
28 // files whose archive members are not yet loaded).
30 // We put all symbols of all files to a SymbolTable, and the
31 // SymbolTable selects the "best" symbols if there are name
32 // conflicts. For example, obviously, a defined symbol is better than
33 // an undefined symbol. Or, if there's a conflict between a lazy and a
34 // undefined, it'll read an archive member to read a real definition
35 // to replace the lazy symbol. The logic is implemented in the
36 // add*() functions, which are called by input files as they are parsed.
37 // There is one add* function per symbol type.
40 void wrap(Symbol
*sym
, Symbol
*real
, Symbol
*wrap
);
42 void addFile(InputFile
*file
);
44 void addCombinedLTOObject();
46 ArrayRef
<Symbol
*> getSymbols() const { return symVector
; }
48 Symbol
*find(StringRef name
);
50 void replace(StringRef name
, Symbol
* sym
);
52 void trace(StringRef name
);
54 Symbol
*addDefinedFunction(StringRef name
, uint32_t flags
, InputFile
*file
,
55 InputFunction
*function
);
56 Symbol
*addDefinedData(StringRef name
, uint32_t flags
, InputFile
*file
,
57 InputChunk
*segment
, uint64_t address
, uint64_t size
);
58 Symbol
*addDefinedGlobal(StringRef name
, uint32_t flags
, InputFile
*file
,
60 Symbol
*addDefinedTag(StringRef name
, uint32_t flags
, InputFile
*file
,
62 Symbol
*addDefinedTable(StringRef name
, uint32_t flags
, InputFile
*file
,
65 Symbol
*addUndefinedFunction(StringRef name
,
66 llvm::Optional
<StringRef
> importName
,
67 llvm::Optional
<StringRef
> importModule
,
68 uint32_t flags
, InputFile
*file
,
69 const WasmSignature
*signature
,
70 bool isCalledDirectly
);
71 Symbol
*addUndefinedData(StringRef name
, uint32_t flags
, InputFile
*file
);
72 Symbol
*addUndefinedGlobal(StringRef name
,
73 llvm::Optional
<StringRef
> importName
,
74 llvm::Optional
<StringRef
> importModule
,
75 uint32_t flags
, InputFile
*file
,
76 const WasmGlobalType
*type
);
77 Symbol
*addUndefinedTable(StringRef name
,
78 llvm::Optional
<StringRef
> importName
,
79 llvm::Optional
<StringRef
> importModule
,
80 uint32_t flags
, InputFile
*file
,
81 const WasmTableType
*type
);
83 TableSymbol
*resolveIndirectFunctionTable(bool required
);
85 void addLazy(ArchiveFile
*f
, const llvm::object::Archive::Symbol
*sym
);
87 bool addComdat(StringRef name
);
89 DefinedData
*addSyntheticDataSymbol(StringRef name
, uint32_t flags
);
90 DefinedGlobal
*addSyntheticGlobal(StringRef name
, uint32_t flags
,
92 DefinedFunction
*addSyntheticFunction(StringRef name
, uint32_t flags
,
93 InputFunction
*function
);
94 DefinedData
*addOptionalDataSymbol(StringRef name
, uint64_t value
= 0);
95 DefinedGlobal
*addOptionalGlobalSymbol(StringRef name
, InputGlobal
*global
);
96 DefinedTable
*addSyntheticTable(StringRef name
, uint32_t flags
,
99 void handleSymbolVariants();
100 void handleWeakUndefines();
101 DefinedFunction
*createUndefinedStub(const WasmSignature
&sig
);
103 std::vector
<ObjFile
*> objectFiles
;
104 std::vector
<SharedFile
*> sharedFiles
;
105 std::vector
<BitcodeFile
*> bitcodeFiles
;
106 std::vector
<InputFunction
*> syntheticFunctions
;
107 std::vector
<InputGlobal
*> syntheticGlobals
;
108 std::vector
<InputTable
*> syntheticTables
;
111 std::pair
<Symbol
*, bool> insert(StringRef name
, const InputFile
*file
);
112 std::pair
<Symbol
*, bool> insertName(StringRef name
);
114 bool getFunctionVariant(Symbol
* sym
, const WasmSignature
*sig
,
115 const InputFile
*file
, Symbol
**out
);
116 InputFunction
*replaceWithUnreachable(Symbol
*sym
, const WasmSignature
&sig
,
117 StringRef debugName
);
118 void replaceWithUndefined(Symbol
*sym
);
120 TableSymbol
*createDefinedIndirectFunctionTable(StringRef name
);
121 TableSymbol
*createUndefinedIndirectFunctionTable(StringRef name
);
123 // Maps symbol names to index into the symVector. -1 means that symbols
124 // is to not yet in the vector but it should have tracing enabled if it is
126 llvm::DenseMap
<llvm::CachedHashStringRef
, int> symMap
;
127 std::vector
<Symbol
*> symVector
;
129 // For certain symbols types, e.g. function symbols, we allow for multiple
130 // variants of the same symbol with different signatures.
131 llvm::DenseMap
<llvm::CachedHashStringRef
, std::vector
<Symbol
*>> symVariants
;
132 llvm::DenseMap
<WasmSignature
, DefinedFunction
*> stubFunctions
;
134 // Comdat groups define "link once" sections. If two comdat groups have the
135 // same name, only one of them is linked, and the other is ignored. This set
136 // is used to uniquify them.
137 llvm::DenseSet
<llvm::CachedHashStringRef
> comdatGroups
;
140 std::unique_ptr
<BitcodeCompiler
> lto
;
143 extern SymbolTable
*symtab
;