blob: a41d8d3b2cd7adadd2bfcf8cde7fcc1a6b719e59 [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"
Rafael Espindola40102eb2015-09-17 18:26:25 +000014#include "llvm/ADT/MapVector.h"
Michael J. Spencer84487f12015-07-24 21:03:07 +000015
16namespace lld {
17namespace elf2 {
Michael J. Spencer84487f12015-07-24 21:03:07 +000018struct Symbol;
19
20// SymbolTable is a bucket of all known symbols, including defined,
21// undefined, or lazy symbols (the last one is symbols in archive
22// files whose archive members are not yet loaded).
23//
24// We put all symbols of all files to a SymbolTable, and the
25// SymbolTable selects the "best" symbols if there are name
26// conflicts. For example, obviously, a defined symbol is better than
27// an undefined symbol. Or, if there's a conflict between a lazy and a
28// undefined, it'll read an archive member to read a real definition
29// to replace the lazy symbol. The logic is implemented in resolve().
Rui Ueyama3ce825e2015-10-09 21:07:25 +000030template <class ELFT> class SymbolTable {
Michael J. Spencer84487f12015-07-24 21:03:07 +000031public:
32 SymbolTable();
33
34 void addFile(std::unique_ptr<InputFile> File);
35
Rafael Espindola67a5da62015-09-17 14:02:10 +000036 bool shouldUseRela() const;
37
Rafael Espindola40102eb2015-09-17 18:26:25 +000038 const llvm::MapVector<StringRef, Symbol *> &getSymbols() const {
Rafael Espindola62b81b82015-08-14 13:07:05 +000039 return Symtab;
40 }
41
Rui Ueyama3ce825e2015-10-09 21:07:25 +000042 const std::vector<std::unique_ptr<ObjectFile<ELFT>>> &getObjectFiles() const {
Rafael Espindola222edc62015-09-03 18:56:20 +000043 return ObjectFiles;
44 }
45
Rui Ueyama3ce825e2015-10-09 21:07:25 +000046 const std::vector<std::unique_ptr<SharedFile<ELFT>>> &getSharedFiles() const {
Rafael Espindola740fafe2015-09-08 19:43:27 +000047 return SharedFiles;
48 }
49
Rui Ueyamaff777682015-10-09 21:12:40 +000050 SymbolBody *addUndefined(StringRef Name);
51 SymbolBody *addUndefinedOpt(StringRef Name);
Rafael Espindola0e604f92015-09-25 18:56:53 +000052 void addSyntheticSym(StringRef Name, OutputSection<ELFT> &Section,
53 typename llvm::object::ELFFile<ELFT>::uintX_t Value);
Rui Ueyama3ce825e2015-10-09 21:07:25 +000054 void addIgnoredSym(StringRef Name);
Rui Ueyamaf8432d92015-10-13 16:34:14 +000055 void finalize();
Rafael Espindola5d413262015-10-01 21:22:26 +000056
Michael J. Spencer84487f12015-07-24 21:03:07 +000057private:
Michael J. Spencer1b348a62015-09-04 22:28:10 +000058 Symbol *insert(SymbolBody *New);
Rafael Espindolaaf707642015-10-12 01:55:32 +000059 void addELFFile(ELFFileBase<ELFT> *File);
Michael J. Spencer1b348a62015-09-04 22:28:10 +000060 void addLazy(Lazy *New);
61 void addMemberFile(Lazy *Body);
Rui Ueyama3d451792015-10-12 18:03:21 +000062 void checkCompatibility(std::unique_ptr<InputFile> &File);
Rui Ueyama3ce825e2015-10-09 21:07:25 +000063 void resolve(SymbolBody *Body);
Rui Ueyamaf8432d92015-10-13 16:34:14 +000064 SymbolBody *find(StringRef Name);
Igor Kudrin65bddea2015-10-09 09:58:39 +000065 void reportConflict(const Twine &Message, const SymbolBody &Old,
66 const SymbolBody &New, bool Warning);
Michael J. Spencer84487f12015-07-24 21:03:07 +000067
Rui Ueyama3ce825e2015-10-09 21:07:25 +000068 std::vector<std::unique_ptr<InputFile>> ArchiveFiles;
Michael J. Spencer1b348a62015-09-04 22:28:10 +000069
Rafael Espindola40102eb2015-09-17 18:26:25 +000070 // The order the global symbols are in is not defined. We can use an arbitrary
71 // order, but it has to be reproducible. That is true even when cross linking.
72 // The default hashing of StringRef produces different results on 32 and 64
73 // bit systems so we use a MapVector. That is arbitrary, deterministic but
74 // a bit inefficient.
75 // FIXME: Experiment with passing in a custom hashing or sorting the symbols
76 // once symbol resolution is finished.
77 llvm::MapVector<StringRef, Symbol *> Symtab;
Michael J. Spencer84487f12015-07-24 21:03:07 +000078 llvm::BumpPtrAllocator Alloc;
Rafael Espindola222edc62015-09-03 18:56:20 +000079
Rafael Espindola444576d2015-10-09 19:25:07 +000080 llvm::DenseSet<StringRef> Comdats;
81
Rafael Espindola222edc62015-09-03 18:56:20 +000082 // The writer needs to infer the machine type from the object files.
Rui Ueyama3ce825e2015-10-09 21:07:25 +000083 std::vector<std::unique_ptr<ObjectFile<ELFT>>> ObjectFiles;
Rafael Espindolaf98d6d82015-09-03 20:03:54 +000084
Rui Ueyama3ce825e2015-10-09 21:07:25 +000085 std::vector<std::unique_ptr<SharedFile<ELFT>>> SharedFiles;
Rafael Espindola6a3b5de2015-10-01 19:52:48 +000086 llvm::DenseSet<StringRef> IncludedSoNames;
Michael J. Spencer84487f12015-07-24 21:03:07 +000087};
88
89} // namespace elf2
90} // namespace lld
91
92#endif