File: SymbolTable.h

package info (click to toggle)
llvm-toolchain-11 1%3A11.0.1-2
  • links: PTS, VCS
  • area: main
  • in suites: bullseye
  • size: 995,808 kB
  • sloc: cpp: 4,767,656; ansic: 760,916; asm: 477,436; python: 170,940; objc: 69,804; lisp: 29,914; sh: 23,855; f90: 18,173; pascal: 7,551; perl: 7,471; ml: 5,603; awk: 3,489; makefile: 2,573; xml: 915; cs: 573; fortran: 503; javascript: 452
file content (129 lines) | stat: -rw-r--r-- 5,084 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
//===- SymbolTable.h --------------------------------------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#ifndef LLD_WASM_SYMBOL_TABLE_H
#define LLD_WASM_SYMBOL_TABLE_H

#include "InputFiles.h"
#include "LTO.h"
#include "Symbols.h"
#include "lld/Common/LLVM.h"
#include "llvm/ADT/CachedHashString.h"
#include "llvm/ADT/DenseSet.h"
#include "llvm/ADT/Optional.h"

namespace lld {
namespace wasm {

class InputSegment;

// SymbolTable is a bucket of all known symbols, including defined,
// undefined, or lazy symbols (the last one is symbols in archive
// files whose archive members are not yet loaded).
//
// We put all symbols of all files to a SymbolTable, and the
// SymbolTable selects the "best" symbols if there are name
// conflicts. For example, obviously, a defined symbol is better than
// an undefined symbol. Or, if there's a conflict between a lazy and a
// undefined, it'll read an archive member to read a real definition
// to replace the lazy symbol. The logic is implemented in the
// add*() functions, which are called by input files as they are parsed.
// There is one add* function per symbol type.
class SymbolTable {
public:
  void wrap(Symbol *sym, Symbol *real, Symbol *wrap);

  void addFile(InputFile *file);

  void addCombinedLTOObject();

  ArrayRef<Symbol *> getSymbols() const { return symVector; }

  Symbol *find(StringRef name);

  void replace(StringRef name, Symbol* sym);

  void trace(StringRef name);

  Symbol *addDefinedFunction(StringRef name, uint32_t flags, InputFile *file,
                             InputFunction *function);
  Symbol *addDefinedData(StringRef name, uint32_t flags, InputFile *file,
                         InputSegment *segment, uint64_t address,
                         uint64_t size);
  Symbol *addDefinedGlobal(StringRef name, uint32_t flags, InputFile *file,
                           InputGlobal *g);
  Symbol *addDefinedEvent(StringRef name, uint32_t flags, InputFile *file,
                          InputEvent *e);

  Symbol *addUndefinedFunction(StringRef name,
                               llvm::Optional<StringRef> importName,
                               llvm::Optional<StringRef> importModule,
                               uint32_t flags, InputFile *file,
                               const WasmSignature *signature,
                               bool isCalledDirectly);
  Symbol *addUndefinedData(StringRef name, uint32_t flags, InputFile *file);
  Symbol *addUndefinedGlobal(StringRef name,
                             llvm::Optional<StringRef> importName,
                             llvm::Optional<StringRef> importModule,
                             uint32_t flags, InputFile *file,
                             const WasmGlobalType *type);

  void addLazy(ArchiveFile *f, const llvm::object::Archive::Symbol *sym);

  bool addComdat(StringRef name);

  DefinedData *addSyntheticDataSymbol(StringRef name, uint32_t flags);
  DefinedGlobal *addSyntheticGlobal(StringRef name, uint32_t flags,
                                    InputGlobal *global);
  DefinedFunction *addSyntheticFunction(StringRef name, uint32_t flags,
                                        InputFunction *function);
  DefinedData *addOptionalDataSymbol(StringRef name, uint32_t value = 0);

  void handleSymbolVariants();
  void handleWeakUndefines();

  std::vector<ObjFile *> objectFiles;
  std::vector<SharedFile *> sharedFiles;
  std::vector<BitcodeFile *> bitcodeFiles;
  std::vector<InputFunction *> syntheticFunctions;
  std::vector<InputGlobal *> syntheticGlobals;

private:
  std::pair<Symbol *, bool> insert(StringRef name, const InputFile *file);
  std::pair<Symbol *, bool> insertName(StringRef name);

  bool getFunctionVariant(Symbol* sym, const WasmSignature *sig,
                          const InputFile *file, Symbol **out);
  InputFunction *replaceWithUnreachable(Symbol *sym, const WasmSignature &sig,
                                        StringRef debugName);

  // Maps symbol names to index into the symVector.  -1 means that symbols
  // is to not yet in the vector but it should have tracing enabled if it is
  // ever added.
  llvm::DenseMap<llvm::CachedHashStringRef, int> symMap;
  std::vector<Symbol *> symVector;

  // For certain symbols types, e.g. function symbols, we allow for multiple
  // variants of the same symbol with different signatures.
  llvm::DenseMap<llvm::CachedHashStringRef, std::vector<Symbol *>> symVariants;

  // Comdat groups define "link once" sections. If two comdat groups have the
  // same name, only one of them is linked, and the other is ignored. This set
  // is used to uniquify them.
  llvm::DenseSet<llvm::CachedHashStringRef> comdatGroups;

  // For LTO.
  std::unique_ptr<BitcodeCompiler> lto;
};

extern SymbolTable *symtab;

} // namespace wasm
} // namespace lld

#endif