xref: /openbsd-src/gnu/llvm/lld/wasm/SymbolTable.h (revision f1dd7b858388b4a23f4f67a4957ec5ff656ebbe8)
1 //===- SymbolTable.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-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #ifndef LLD_WASM_SYMBOL_TABLE_H
10 #define LLD_WASM_SYMBOL_TABLE_H
11 
12 #include "InputFiles.h"
13 #include "LTO.h"
14 #include "Symbols.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 
20 namespace lld {
21 namespace wasm {
22 
23 class InputSegment;
24 
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).
28 //
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.
37 class SymbolTable {
38 public:
39   void wrap(Symbol *sym, Symbol *real, Symbol *wrap);
40 
41   void addFile(InputFile *file);
42 
43   void addCombinedLTOObject();
44 
45   ArrayRef<Symbol *> getSymbols() const { return symVector; }
46 
47   Symbol *find(StringRef name);
48 
49   void replace(StringRef name, Symbol* sym);
50 
51   void trace(StringRef name);
52 
53   Symbol *addDefinedFunction(StringRef name, uint32_t flags, InputFile *file,
54                              InputFunction *function);
55   Symbol *addDefinedData(StringRef name, uint32_t flags, InputFile *file,
56                          InputSegment *segment, uint64_t address,
57                          uint64_t size);
58   Symbol *addDefinedGlobal(StringRef name, uint32_t flags, InputFile *file,
59                            InputGlobal *g);
60   Symbol *addDefinedEvent(StringRef name, uint32_t flags, InputFile *file,
61                           InputEvent *e);
62 
63   Symbol *addUndefinedFunction(StringRef name,
64                                llvm::Optional<StringRef> importName,
65                                llvm::Optional<StringRef> importModule,
66                                uint32_t flags, InputFile *file,
67                                const WasmSignature *signature,
68                                bool isCalledDirectly);
69   Symbol *addUndefinedData(StringRef name, uint32_t flags, InputFile *file);
70   Symbol *addUndefinedGlobal(StringRef name,
71                              llvm::Optional<StringRef> importName,
72                              llvm::Optional<StringRef> importModule,
73                              uint32_t flags, InputFile *file,
74                              const WasmGlobalType *type);
75 
76   void addLazy(ArchiveFile *f, const llvm::object::Archive::Symbol *sym);
77 
78   bool addComdat(StringRef name);
79 
80   DefinedData *addSyntheticDataSymbol(StringRef name, uint32_t flags);
81   DefinedGlobal *addSyntheticGlobal(StringRef name, uint32_t flags,
82                                     InputGlobal *global);
83   DefinedFunction *addSyntheticFunction(StringRef name, uint32_t flags,
84                                         InputFunction *function);
85   DefinedData *addOptionalDataSymbol(StringRef name, uint32_t value = 0);
86 
87   void handleSymbolVariants();
88   void handleWeakUndefines();
89 
90   std::vector<ObjFile *> objectFiles;
91   std::vector<SharedFile *> sharedFiles;
92   std::vector<BitcodeFile *> bitcodeFiles;
93   std::vector<InputFunction *> syntheticFunctions;
94   std::vector<InputGlobal *> syntheticGlobals;
95 
96 private:
97   std::pair<Symbol *, bool> insert(StringRef name, const InputFile *file);
98   std::pair<Symbol *, bool> insertName(StringRef name);
99 
100   bool getFunctionVariant(Symbol* sym, const WasmSignature *sig,
101                           const InputFile *file, Symbol **out);
102   InputFunction *replaceWithUnreachable(Symbol *sym, const WasmSignature &sig,
103                                         StringRef debugName);
104 
105   // Maps symbol names to index into the symVector.  -1 means that symbols
106   // is to not yet in the vector but it should have tracing enabled if it is
107   // ever added.
108   llvm::DenseMap<llvm::CachedHashStringRef, int> symMap;
109   std::vector<Symbol *> symVector;
110 
111   // For certain symbols types, e.g. function symbols, we allow for multiple
112   // variants of the same symbol with different signatures.
113   llvm::DenseMap<llvm::CachedHashStringRef, std::vector<Symbol *>> symVariants;
114 
115   // Comdat groups define "link once" sections. If two comdat groups have the
116   // same name, only one of them is linked, and the other is ignored. This set
117   // is used to uniquify them.
118   llvm::DenseSet<llvm::CachedHashStringRef> comdatGroups;
119 
120   // For LTO.
121   std::unique_ptr<BitcodeCompiler> lto;
122 };
123 
124 extern SymbolTable *symtab;
125 
126 } // namespace wasm
127 } // namespace lld
128 
129 #endif
130