xref: /openbsd-src/gnu/llvm/lld/wasm/SymbolTable.h (revision 1a8dbaac879b9f3335ad7fb25429ce63ac1d6bac)
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 
19 namespace lld {
20 namespace wasm {
21 
22 class InputSegment;
23 
24 // SymbolTable is a bucket of all known symbols, including defined,
25 // undefined, or lazy symbols (the last one is symbols in archive
26 // files whose archive members are not yet loaded).
27 //
28 // We put all symbols of all files to a SymbolTable, and the
29 // SymbolTable selects the "best" symbols if there are name
30 // conflicts. For example, obviously, a defined symbol is better than
31 // an undefined symbol. Or, if there's a conflict between a lazy and a
32 // undefined, it'll read an archive member to read a real definition
33 // to replace the lazy symbol. The logic is implemented in the
34 // add*() functions, which are called by input files as they are parsed.
35 // There is one add* function per symbol type.
36 class SymbolTable {
37 public:
38   void wrap(Symbol *sym, Symbol *real, Symbol *wrap);
39 
40   void addFile(InputFile *file);
41 
42   void addCombinedLTOObject();
43 
44   ArrayRef<Symbol *> getSymbols() const { return symVector; }
45 
46   Symbol *find(StringRef name);
47 
48   void replace(StringRef name, Symbol* sym);
49 
50   void trace(StringRef name);
51 
52   Symbol *addDefinedFunction(StringRef name, uint32_t flags, InputFile *file,
53                              InputFunction *function);
54   Symbol *addDefinedData(StringRef name, uint32_t flags, InputFile *file,
55                          InputSegment *segment, uint32_t address,
56                          uint32_t size);
57   Symbol *addDefinedGlobal(StringRef name, uint32_t flags, InputFile *file,
58                            InputGlobal *g);
59   Symbol *addDefinedEvent(StringRef name, uint32_t flags, InputFile *file,
60                           InputEvent *e);
61 
62   Symbol *addUndefinedFunction(StringRef name, StringRef importName,
63                                StringRef importModule, uint32_t flags,
64                                InputFile *file, const WasmSignature *signature,
65                                bool isCalledDirectly);
66   Symbol *addUndefinedData(StringRef name, uint32_t flags, InputFile *file);
67   Symbol *addUndefinedGlobal(StringRef name, StringRef importName,
68                              StringRef importModule,  uint32_t flags,
69                              InputFile *file, const WasmGlobalType *type);
70 
71   void addLazy(ArchiveFile *f, const llvm::object::Archive::Symbol *sym);
72 
73   bool addComdat(StringRef name);
74 
75   DefinedData *addSyntheticDataSymbol(StringRef name, uint32_t flags);
76   DefinedGlobal *addSyntheticGlobal(StringRef name, uint32_t flags,
77                                     InputGlobal *global);
78   DefinedFunction *addSyntheticFunction(StringRef name, uint32_t flags,
79                                         InputFunction *function);
80   DefinedData *addOptionalDataSymbol(StringRef name, uint32_t value = 0);
81 
82   void handleSymbolVariants();
83   void handleWeakUndefines();
84 
85   std::vector<ObjFile *> objectFiles;
86   std::vector<SharedFile *> sharedFiles;
87   std::vector<BitcodeFile *> bitcodeFiles;
88   std::vector<InputFunction *> syntheticFunctions;
89   std::vector<InputGlobal *> syntheticGlobals;
90 
91 private:
92   std::pair<Symbol *, bool> insert(StringRef name, const InputFile *file);
93   std::pair<Symbol *, bool> insertName(StringRef name);
94 
95   bool getFunctionVariant(Symbol* sym, const WasmSignature *sig,
96                           const InputFile *file, Symbol **out);
97   InputFunction *replaceWithUnreachable(Symbol *sym, const WasmSignature &sig,
98                                         StringRef debugName);
99 
100   // Maps symbol names to index into the symVector.  -1 means that symbols
101   // is to not yet in the vector but it should have tracing enabled if it is
102   // ever added.
103   llvm::DenseMap<llvm::CachedHashStringRef, int> symMap;
104   std::vector<Symbol *> symVector;
105 
106   // For certain symbols types, e.g. function symbols, we allow for muliple
107   // variants of the same symbol with different signatures.
108   llvm::DenseMap<llvm::CachedHashStringRef, std::vector<Symbol *>> symVariants;
109 
110   // Comdat groups define "link once" sections. If two comdat groups have the
111   // same name, only one of them is linked, and the other is ignored. This set
112   // is used to uniquify them.
113   llvm::DenseSet<llvm::CachedHashStringRef> comdatGroups;
114 
115   // For LTO.
116   std::unique_ptr<BitcodeCompiler> lto;
117 };
118 
119 extern SymbolTable *symtab;
120 
121 } // namespace wasm
122 } // namespace lld
123 
124 #endif
125