blob: 507af8d2be75d8e6d7d36d5dfc3d020b0cbaaf05 [file] [log] [blame]
Rafael Espindolabeee25e2015-08-14 14:12:54 +00001//===- SymbolTable.h --------------------------------------------*- C++ -*-===//
Michael J. Spencer84487f12015-07-24 21:03:07 +00002//
Chandler Carruth2946cd72019-01-19 08:50:56 +00003// 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
Michael J. Spencer84487f12015-07-24 21:03:07 +00006//
7//===----------------------------------------------------------------------===//
8
9#ifndef LLD_ELF_SYMBOL_TABLE_H
10#define LLD_ELF_SYMBOL_TABLE_H
11
12#include "InputFiles.h"
Rui Ueyamad8f8abb2019-05-28 06:33:06 +000013#include "Symbols.h"
Rui Ueyamaee173712018-02-28 17:38:19 +000014#include "lld/Common/Strings.h"
Justin Lebar3c11e932016-10-18 17:50:36 +000015#include "llvm/ADT/CachedHashString.h"
Rafael Espindola7f0b7272016-04-14 20:42:43 +000016#include "llvm/ADT/DenseMap.h"
Rui Ueyamad8f8abb2019-05-28 06:33:06 +000017#include "llvm/ADT/STLExtras.h"
Michael J. Spencer84487f12015-07-24 21:03:07 +000018
19namespace lld {
Rafael Espindolae0df00b2016-02-28 00:25:54 +000020namespace elf {
Rui Ueyama7d476192019-05-16 02:14:00 +000021
Michael J. Spencer84487f12015-07-24 21:03:07 +000022// SymbolTable is a bucket of all known symbols, including defined,
23// undefined, or lazy symbols (the last one is symbols in archive
24// files whose archive members are not yet loaded).
25//
26// We put all symbols of all files to a SymbolTable, and the
27// SymbolTable selects the "best" symbols if there are name
28// conflicts. For example, obviously, a defined symbol is better than
29// an undefined symbol. Or, if there's a conflict between a lazy and a
30// undefined, it'll read an archive member to read a real definition
Peter Collingbourne4f952702016-05-01 04:55:03 +000031// to replace the lazy symbol. The logic is implemented in the
32// add*() functions, which are called by input files as they are parsed. There
33// is one add* function per symbol type.
Rafael Espindola244ef982017-07-26 18:42:48 +000034class SymbolTable {
Fangrui Songa2fc9642019-11-20 11:16:15 -080035 struct FilterOutPlaceholder {
36 bool operator()(Symbol *S) const { return !S->isPlaceholder(); }
37 };
38 using iterator = llvm::filter_iterator<std::vector<Symbol *>::const_iterator,
39 FilterOutPlaceholder>;
Michael J. Spencer84487f12015-07-24 21:03:07 +000040
Fangrui Songa2fc9642019-11-20 11:16:15 -080041public:
42 llvm::iterator_range<iterator> symbols() const {
43 return llvm::make_filter_range(symVector, FilterOutPlaceholder());
Rui Ueyamad8f8abb2019-05-28 06:33:06 +000044 }
Rafael Espindola740fafe2015-09-08 19:43:27 +000045
Fangrui Songa2fc9642019-11-20 11:16:15 -080046 void wrap(Symbol *sym, Symbol *real, Symbol *wrap);
47
Rui Ueyama3837f422019-07-10 05:00:37 +000048 Symbol *insert(StringRef name);
Rafael Espindola244ef982017-07-26 18:42:48 +000049
Fangrui Songab04ad62019-08-13 06:19:39 +000050 Symbol *addSymbol(const Symbol &newSym);
Petr Hosek5e51f7d2017-02-21 22:32:51 +000051
Peter Collingbourne66ac1d62016-04-22 20:21:26 +000052 void scanVersionScript();
Rui Ueyamad60dae8a2016-06-23 07:00:17 +000053
Rui Ueyama3837f422019-07-10 05:00:37 +000054 Symbol *find(StringRef name);
Rui Ueyama69c778c2016-07-17 17:50:09 +000055
Rafael Espindolad72d97b2017-09-08 18:16:59 +000056 void handleDynamicList();
57
Fangrui Songb4744d32019-02-01 02:25:05 +000058 // Set of .so files to not link the same shared object file more than once.
Rui Ueyama3837f422019-07-10 05:00:37 +000059 llvm::DenseMap<StringRef, SharedFile *> soNames;
Fangrui Songb4744d32019-02-01 02:25:05 +000060
Fangrui Songb72b0912019-05-22 09:06:42 +000061 // Comdat groups define "link once" sections. If two comdat groups have the
62 // same name, only one of them is linked, and the other is ignored. This map
63 // is used to uniquify them.
Rui Ueyama3837f422019-07-10 05:00:37 +000064 llvm::DenseMap<llvm::CachedHashStringRef, const InputFile *> comdatGroups;
Fangrui Songb72b0912019-05-22 09:06:42 +000065
Michael J. Spencer84487f12015-07-24 21:03:07 +000066private:
Rui Ueyama3837f422019-07-10 05:00:37 +000067 std::vector<Symbol *> findByVersion(SymbolVersion ver);
68 std::vector<Symbol *> findAllByVersion(SymbolVersion ver);
Rui Ueyama82492142016-11-15 18:41:52 +000069
Rui Ueyamaf52496e2017-11-03 21:21:47 +000070 llvm::StringMap<std::vector<Symbol *>> &getDemangledSyms();
Rui Ueyama3837f422019-07-10 05:00:37 +000071 void assignExactVersion(SymbolVersion ver, uint16_t versionId,
72 StringRef versionName);
73 void assignWildcardVersion(SymbolVersion ver, uint16_t versionId);
George Rimar50dcece2016-07-16 12:26:39 +000074
Rafael Espindola40102eb2015-09-17 18:26:25 +000075 // The order the global symbols are in is not defined. We can use an arbitrary
76 // order, but it has to be reproducible. That is true even when cross linking.
77 // The default hashing of StringRef produces different results on 32 and 64
Rafael Espindola7f0b7272016-04-14 20:42:43 +000078 // bit systems so we use a map to a vector. That is arbitrary, deterministic
79 // but a bit inefficient.
Rafael Espindola40102eb2015-09-17 18:26:25 +000080 // FIXME: Experiment with passing in a custom hashing or sorting the symbols
81 // once symbol resolution is finished.
Rui Ueyama3837f422019-07-10 05:00:37 +000082 llvm::DenseMap<llvm::CachedHashStringRef, int> symMap;
83 std::vector<Symbol *> symVector;
Rafael Espindola222edc62015-09-03 18:56:20 +000084
Rui Ueyama82492142016-11-15 18:41:52 +000085 // A map from demangled symbol names to their symbol objects.
86 // This mapping is 1:N because two symbols with different versions
87 // can have the same name. We use this map to handle "extern C++ {}"
88 // directive in version scripts.
Rui Ueyama3837f422019-07-10 05:00:37 +000089 llvm::Optional<llvm::StringMap<std::vector<Symbol *>>> demangledSyms;
Michael J. Spencer84487f12015-07-24 21:03:07 +000090};
91
Rui Ueyama3837f422019-07-10 05:00:37 +000092extern SymbolTable *symtab;
Rui Ueyamabbf154c2019-05-17 01:55:20 +000093
Rafael Espindolae0df00b2016-02-28 00:25:54 +000094} // namespace elf
Michael J. Spencer84487f12015-07-24 21:03:07 +000095} // namespace lld
96
97#endif