blob: 5e6d44dfe4f9d5009738be1cfaf9d39f24c135fe [file] [log] [blame]
Rafael Espindolabeee25e2015-08-14 14:12:54 +00001//===- SymbolTable.h --------------------------------------------*- C++ -*-===//
Michael J. Spencer84487f12015-07-24 21:03:07 +00002//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef LLD_ELF_SYMBOL_TABLE_H
11#define LLD_ELF_SYMBOL_TABLE_H
12
13#include "InputFiles.h"
Rui Ueyama25992482016-03-22 20:52:10 +000014#include "LTO.h"
Rui Ueyamaee173712018-02-28 17:38:19 +000015#include "lld/Common/Strings.h"
Justin Lebar3c11e932016-10-18 17:50:36 +000016#include "llvm/ADT/CachedHashString.h"
Rafael Espindola7f0b7272016-04-14 20:42:43 +000017#include "llvm/ADT/DenseMap.h"
Michael J. Spencer84487f12015-07-24 21:03:07 +000018
19namespace lld {
Rafael Espindolae0df00b2016-02-28 00:25:54 +000020namespace elf {
Rafael Espindolad26b52f2017-12-09 16:56:18 +000021class Defined;
22class SectionBase;
Sam Cleggc0909622017-06-30 00:34:35 +000023
Michael J. Spencer84487f12015-07-24 21:03:07 +000024// 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
Peter Collingbourne4f952702016-05-01 04:55:03 +000033// to replace the lazy symbol. The logic is implemented in the
34// add*() functions, which are called by input files as they are parsed. There
35// is one add* function per symbol type.
Rafael Espindola244ef982017-07-26 18:42:48 +000036class SymbolTable {
Michael J. Spencer84487f12015-07-24 21:03:07 +000037public:
Rafael Espindola244ef982017-07-26 18:42:48 +000038 template <class ELFT> void addFile(InputFile *File);
39 template <class ELFT> void addCombinedLTOObject();
Rafael Espindola244ef982017-07-26 18:42:48 +000040 template <class ELFT> void addSymbolWrap(StringRef Name);
Rui Ueyamadc0b0b02017-11-04 23:09:43 +000041 void applySymbolWrap();
Michael J. Spencer84487f12015-07-24 21:03:07 +000042
Rui Ueyamaf52496e2017-11-03 21:21:47 +000043 ArrayRef<Symbol *> getSymbols() const { return SymVector; }
Rafael Espindola740fafe2015-09-08 19:43:27 +000044
Peter Collingbournee9a9e0a2017-11-06 04:35:31 +000045 Defined *addAbsolute(StringRef Name,
46 uint8_t Visibility = llvm::ELF::STV_HIDDEN,
47 uint8_t Binding = llvm::ELF::STB_GLOBAL);
Rui Ueyama79c73732016-01-08 21:53:28 +000048
Rui Ueyamaf52496e2017-11-03 21:21:47 +000049 template <class ELFT> Symbol *addUndefined(StringRef Name);
Rafael Espindola244ef982017-07-26 18:42:48 +000050 template <class ELFT>
Rafael Espindolabec37652017-11-17 01:37:50 +000051 Symbol *addUndefined(StringRef Name, uint8_t Binding, uint8_t StOther,
52 uint8_t Type, bool CanOmitFromDynSym, InputFile *File);
Rui Ueyamaf52496e2017-11-03 21:21:47 +000053 Symbol *addRegular(StringRef Name, uint8_t StOther, uint8_t Type,
54 uint64_t Value, uint64_t Size, uint8_t Binding,
55 SectionBase *Section, InputFile *File);
Rui Ueyama1bdaf3e2016-11-09 23:37:40 +000056
Rafael Espindola244ef982017-07-26 18:42:48 +000057 template <class ELFT>
Rafael Espindolaa32ddc42017-12-20 16:28:19 +000058 void addShared(StringRef Name, SharedFile<ELFT> &F,
Rui Ueyama7f9694a2017-10-28 20:15:56 +000059 const typename ELFT::Sym &Sym, uint32_t Alignment,
Rafael Espindola8f619ab2017-12-12 01:45:49 +000060 uint32_t VerdefIndex);
Peter Collingbourne4f952702016-05-01 04:55:03 +000061
Rafael Espindola244ef982017-07-26 18:42:48 +000062 template <class ELFT>
Peter Collingbourne09e04af2018-02-16 20:23:54 +000063 void addLazyArchive(StringRef Name, ArchiveFile &F,
64 const llvm::object::Archive::Symbol S);
Rui Ueyamade3d0cc2017-09-30 12:41:34 +000065
Rui Ueyama709fb2bb12017-07-26 22:13:32 +000066 template <class ELFT> void addLazyObject(StringRef Name, LazyObjFile &Obj);
Rafael Espindola244ef982017-07-26 18:42:48 +000067
Rui Ueyamaf52496e2017-11-03 21:21:47 +000068 Symbol *addBitcode(StringRef Name, uint8_t Binding, uint8_t StOther,
Rafael Espindolaf1687122017-12-20 16:16:40 +000069 uint8_t Type, bool CanOmitFromDynSym, BitcodeFile &File);
Peter Collingbourne4f952702016-05-01 04:55:03 +000070
Rui Ueyamaf52496e2017-11-03 21:21:47 +000071 Symbol *addCommon(StringRef Name, uint64_t Size, uint32_t Alignment,
72 uint8_t Binding, uint8_t StOther, uint8_t Type,
Rafael Espindola7b5cc6c2017-12-20 16:19:48 +000073 InputFile &File);
Peter Collingbourne4f952702016-05-01 04:55:03 +000074
Rui Ueyamaf52496e2017-11-03 21:21:47 +000075 std::pair<Symbol *, bool> insert(StringRef Name);
76 std::pair<Symbol *, bool> insert(StringRef Name, uint8_t Type,
77 uint8_t Visibility, bool CanOmitFromDynSym,
78 InputFile *File);
Petr Hosek5e51f7d2017-02-21 22:32:51 +000079
Rui Ueyamacc013f62018-04-03 18:01:18 +000080 template <class ELFT> void fetchLazy(Symbol *Sym);
George Rimar1ef746b2018-04-03 17:16:52 +000081
Peter Collingbourne66ac1d62016-04-22 20:21:26 +000082 void scanVersionScript();
Rui Ueyamad60dae8a2016-06-23 07:00:17 +000083
Rui Ueyamaf52496e2017-11-03 21:21:47 +000084 Symbol *find(StringRef Name);
Rui Ueyama69c778c2016-07-17 17:50:09 +000085
86 void trace(StringRef Name);
Rafael Espindola5d413262015-10-01 21:22:26 +000087
Rafael Espindolad72d97b2017-09-08 18:16:59 +000088 void handleDynamicList();
89
Michael J. Spencer84487f12015-07-24 21:03:07 +000090private:
Rui Ueyamaf52496e2017-11-03 21:21:47 +000091 std::vector<Symbol *> findByVersion(SymbolVersion Ver);
92 std::vector<Symbol *> findAllByVersion(SymbolVersion Ver);
Rui Ueyama82492142016-11-15 18:41:52 +000093
Rui Ueyamaf52496e2017-11-03 21:21:47 +000094 llvm::StringMap<std::vector<Symbol *>> &getDemangledSyms();
Rui Ueyamaea265042016-09-13 20:51:30 +000095 void handleAnonymousVersion();
Rui Ueyamada805c42016-11-17 03:39:21 +000096 void assignExactVersion(SymbolVersion Ver, uint16_t VersionId,
Rui Ueyama94bcfae2016-11-17 02:09:42 +000097 StringRef VersionName);
Rui Ueyamada805c42016-11-17 03:39:21 +000098 void assignWildcardVersion(SymbolVersion Ver, uint16_t VersionId);
George Rimar50dcece2016-07-16 12:26:39 +000099
Rafael Espindola40102eb2015-09-17 18:26:25 +0000100 // The order the global symbols are in is not defined. We can use an arbitrary
101 // order, but it has to be reproducible. That is true even when cross linking.
102 // The default hashing of StringRef produces different results on 32 and 64
Rafael Espindola7f0b7272016-04-14 20:42:43 +0000103 // bit systems so we use a map to a vector. That is arbitrary, deterministic
104 // but a bit inefficient.
Rafael Espindola40102eb2015-09-17 18:26:25 +0000105 // FIXME: Experiment with passing in a custom hashing or sorting the symbols
106 // once symbol resolution is finished.
Sam Clegga80d94d2017-11-27 23:16:06 +0000107 llvm::DenseMap<llvm::CachedHashStringRef, int> SymMap;
Rui Ueyamaf52496e2017-11-03 21:21:47 +0000108 std::vector<Symbol *> SymVector;
Rafael Espindola222edc62015-09-03 18:56:20 +0000109
Rui Ueyama683564e2016-01-08 22:14:15 +0000110 // 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.
Rafael Espindola1c2baad2017-05-25 21:53:02 +0000113 llvm::DenseSet<llvm::CachedHashStringRef> ComdatGroups;
Rafael Espindola444576d2015-10-09 19:25:07 +0000114
Rui Ueyama683564e2016-01-08 22:14:15 +0000115 // Set of .so files to not link the same shared object file more than once.
Rui Ueyama131e0ff2016-01-08 22:17:42 +0000116 llvm::DenseSet<StringRef> SoNames;
Rui Ueyama25992482016-03-22 20:52:10 +0000117
Rui Ueyama82492142016-11-15 18:41:52 +0000118 // A map from demangled symbol names to their symbol objects.
119 // This mapping is 1:N because two symbols with different versions
120 // can have the same name. We use this map to handle "extern C++ {}"
121 // directive in version scripts.
Rui Ueyamaf52496e2017-11-03 21:21:47 +0000122 llvm::Optional<llvm::StringMap<std::vector<Symbol *>>> DemangledSyms;
Rui Ueyama82492142016-11-15 18:41:52 +0000123
Rui Ueyamadc0b0b02017-11-04 23:09:43 +0000124 struct WrappedSymbol {
125 Symbol *Sym;
126 Symbol *Real;
127 Symbol *Wrap;
Rui Ueyamabbfe33c2017-09-25 00:57:18 +0000128 };
129
Rafael Espindola46935082017-10-06 20:09:34 +0000130 // For -wrap.
Rui Ueyamadc0b0b02017-11-04 23:09:43 +0000131 std::vector<WrappedSymbol> WrappedSymbols;
Rafael Espindola46935082017-10-06 20:09:34 +0000132
Rui Ueyama82492142016-11-15 18:41:52 +0000133 // For LTO.
Davide Italiano3bfa0812016-11-26 05:37:04 +0000134 std::unique_ptr<BitcodeCompiler> LTO;
Michael J. Spencer84487f12015-07-24 21:03:07 +0000135};
136
Rafael Espindola244ef982017-07-26 18:42:48 +0000137extern SymbolTable *Symtab;
Rafael Espindolae0df00b2016-02-28 00:25:54 +0000138} // namespace elf
Michael J. Spencer84487f12015-07-24 21:03:07 +0000139} // namespace lld
140
141#endif