xref: /openbsd/gnu/llvm/lld/ELF/SymbolTable.h (revision dfe94b16)
1ece8a530Spatrick //===- SymbolTable.h --------------------------------------------*- C++ -*-===//
2ece8a530Spatrick //
3ece8a530Spatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4ece8a530Spatrick // See https://llvm.org/LICENSE.txt for license information.
5ece8a530Spatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6ece8a530Spatrick //
7ece8a530Spatrick //===----------------------------------------------------------------------===//
8ece8a530Spatrick 
9ece8a530Spatrick #ifndef LLD_ELF_SYMBOL_TABLE_H
10ece8a530Spatrick #define LLD_ELF_SYMBOL_TABLE_H
11ece8a530Spatrick 
12ece8a530Spatrick #include "Symbols.h"
13ece8a530Spatrick #include "llvm/ADT/CachedHashString.h"
14ece8a530Spatrick #include "llvm/ADT/DenseMap.h"
15*dfe94b16Srobert #include "llvm/Support/Compiler.h"
16ece8a530Spatrick 
17*dfe94b16Srobert namespace lld::elf {
18*dfe94b16Srobert 
19*dfe94b16Srobert class InputFile;
20*dfe94b16Srobert class SharedFile;
21ece8a530Spatrick 
22ece8a530Spatrick // SymbolTable is a bucket of all known symbols, including defined,
23ece8a530Spatrick // undefined, or lazy symbols (the last one is symbols in archive
24ece8a530Spatrick // files whose archive members are not yet loaded).
25ece8a530Spatrick //
26ece8a530Spatrick // We put all symbols of all files to a SymbolTable, and the
27ece8a530Spatrick // SymbolTable selects the "best" symbols if there are name
28ece8a530Spatrick // conflicts. For example, obviously, a defined symbol is better than
29ece8a530Spatrick // an undefined symbol. Or, if there's a conflict between a lazy and a
30ece8a530Spatrick // undefined, it'll read an archive member to read a real definition
31ece8a530Spatrick // to replace the lazy symbol. The logic is implemented in the
32ece8a530Spatrick // add*() functions, which are called by input files as they are parsed. There
33ece8a530Spatrick // is one add* function per symbol type.
34ece8a530Spatrick class SymbolTable {
35ece8a530Spatrick public:
getSymbols()36*dfe94b16Srobert   ArrayRef<Symbol *> getSymbols() const { return symVector; }
37ece8a530Spatrick 
38ece8a530Spatrick   void wrap(Symbol *sym, Symbol *real, Symbol *wrap);
39ece8a530Spatrick 
40ece8a530Spatrick   Symbol *insert(StringRef name);
41ece8a530Spatrick 
addSymbol(const T & newSym)42*dfe94b16Srobert   template <typename T> Symbol *addSymbol(const T &newSym) {
43*dfe94b16Srobert     Symbol *sym = insert(newSym.getName());
44*dfe94b16Srobert     sym->resolve(newSym);
45*dfe94b16Srobert     return sym;
46*dfe94b16Srobert   }
47*dfe94b16Srobert   Symbol *addAndCheckDuplicate(const Defined &newSym);
48ece8a530Spatrick 
49ece8a530Spatrick   void scanVersionScript();
50ece8a530Spatrick 
51ece8a530Spatrick   Symbol *find(StringRef name);
52ece8a530Spatrick 
53ece8a530Spatrick   void handleDynamicList();
54ece8a530Spatrick 
55ece8a530Spatrick   // Set of .so files to not link the same shared object file more than once.
56*dfe94b16Srobert   llvm::DenseMap<llvm::CachedHashStringRef, SharedFile *> soNames;
57ece8a530Spatrick 
58ece8a530Spatrick   // Comdat groups define "link once" sections. If two comdat groups have the
59ece8a530Spatrick   // same name, only one of them is linked, and the other is ignored. This map
60ece8a530Spatrick   // is used to uniquify them.
61ece8a530Spatrick   llvm::DenseMap<llvm::CachedHashStringRef, const InputFile *> comdatGroups;
62ece8a530Spatrick 
63ece8a530Spatrick private:
64*dfe94b16Srobert   SmallVector<Symbol *, 0> findByVersion(SymbolVersion ver);
65*dfe94b16Srobert   SmallVector<Symbol *, 0> findAllByVersion(SymbolVersion ver,
661cf9926bSpatrick                                             bool includeNonDefault);
67ece8a530Spatrick 
68*dfe94b16Srobert   llvm::StringMap<SmallVector<Symbol *, 0>> &getDemangledSyms();
691cf9926bSpatrick   bool assignExactVersion(SymbolVersion ver, uint16_t versionId,
701cf9926bSpatrick                           StringRef versionName, bool includeNonDefault);
711cf9926bSpatrick   void assignWildcardVersion(SymbolVersion ver, uint16_t versionId,
721cf9926bSpatrick                              bool includeNonDefault);
73ece8a530Spatrick 
74ece8a530Spatrick   // The order the global symbols are in is not defined. We can use an arbitrary
75ece8a530Spatrick   // order, but it has to be reproducible. That is true even when cross linking.
76ece8a530Spatrick   // The default hashing of StringRef produces different results on 32 and 64
77ece8a530Spatrick   // bit systems so we use a map to a vector. That is arbitrary, deterministic
78ece8a530Spatrick   // but a bit inefficient.
79ece8a530Spatrick   // FIXME: Experiment with passing in a custom hashing or sorting the symbols
80ece8a530Spatrick   // once symbol resolution is finished.
81ece8a530Spatrick   llvm::DenseMap<llvm::CachedHashStringRef, int> symMap;
82*dfe94b16Srobert   SmallVector<Symbol *, 0> symVector;
83ece8a530Spatrick 
84ece8a530Spatrick   // A map from demangled symbol names to their symbol objects.
85ece8a530Spatrick   // This mapping is 1:N because two symbols with different versions
86ece8a530Spatrick   // can have the same name. We use this map to handle "extern C++ {}"
87ece8a530Spatrick   // directive in version scripts.
88*dfe94b16Srobert   std::optional<llvm::StringMap<SmallVector<Symbol *, 0>>> demangledSyms;
89ece8a530Spatrick };
90ece8a530Spatrick 
91*dfe94b16Srobert LLVM_LIBRARY_VISIBILITY extern SymbolTable symtab;
92ece8a530Spatrick 
93*dfe94b16Srobert } // namespace lld::elf
94ece8a530Spatrick 
95ece8a530Spatrick #endif
96