blob: 1e189f5dec5e6eccc6839cea4db15b5cdcb748f7 [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().
Rafael Espindola2ffdd4d2015-08-04 14:29:01 +000030class SymbolTable {
Michael J. Spencer84487f12015-07-24 21:03:07 +000031public:
32 SymbolTable();
33
34 void addFile(std::unique_ptr<InputFile> File);
35
Rafael Espindolaf98d6d82015-09-03 20:03:54 +000036 const ELFFileBase *getFirstELF() const {
Rafael Espindola8aeb13f2015-09-03 19:13:13 +000037 if (!ObjectFiles.empty())
38 return ObjectFiles[0].get();
Rafael Espindolaf98d6d82015-09-03 20:03:54 +000039 if (!SharedFiles.empty())
40 return SharedFiles[0].get();
Rafael Espindola8aeb13f2015-09-03 19:13:13 +000041 return nullptr;
42 }
43
Rafael Espindola67a5da62015-09-17 14:02:10 +000044 bool shouldUseRela() const;
45
Rafael Espindola40102eb2015-09-17 18:26:25 +000046 const llvm::MapVector<StringRef, Symbol *> &getSymbols() const {
Rafael Espindola62b81b82015-08-14 13:07:05 +000047 return Symtab;
48 }
49
Rafael Espindola222edc62015-09-03 18:56:20 +000050 const std::vector<std::unique_ptr<ObjectFileBase>> &getObjectFiles() const {
51 return ObjectFiles;
52 }
53
Rafael Espindola740fafe2015-09-08 19:43:27 +000054 const std::vector<std::unique_ptr<SharedFileBase>> &getSharedFiles() const {
55 return SharedFiles;
56 }
57
Michael J. Spencer546c64c2015-09-08 22:34:57 +000058 SymbolBody *getEntrySym() const {
Rafael Espindola4340aad2015-09-11 22:42:45 +000059 if (!EntrySym)
60 return nullptr;
Michael J. Spencerac5f0482015-09-08 22:51:46 +000061 return EntrySym->getReplacement();
Michael J. Spencer546c64c2015-09-08 22:34:57 +000062 }
63
Rafael Espindola0e604f92015-09-25 18:56:53 +000064 template <class ELFT>
65 void addSyntheticSym(StringRef Name, OutputSection<ELFT> &Section,
66 typename llvm::object::ELFFile<ELFT>::uintX_t Value);
67
Michael J. Spencer84487f12015-07-24 21:03:07 +000068private:
Michael J. Spencer1b348a62015-09-04 22:28:10 +000069 Symbol *insert(SymbolBody *New);
Rafael Espindola824d1a92015-09-04 00:09:43 +000070 template <class ELFT> void addELFFile(ELFFileBase *File);
Rafael Espindolaf98d6d82015-09-03 20:03:54 +000071 void addELFFile(ELFFileBase *File);
Michael J. Spencer1b348a62015-09-04 22:28:10 +000072 void addLazy(Lazy *New);
73 void addMemberFile(Lazy *Body);
Michael J. Spencer84487f12015-07-24 21:03:07 +000074
Rafael Espindola01205f72015-09-22 18:19:46 +000075 template <class ELFT> void init(uint16_t EMachine);
Rafael Espindoladaa92a62015-08-31 01:16:19 +000076 template <class ELFT> void resolve(SymbolBody *Body);
Rafael Espindola1a49e582015-09-23 14:10:24 +000077 template <class ELFT>
Rafael Espindola5a5fdf72015-09-24 12:58:44 +000078 void dupError(const SymbolBody &Old, const SymbolBody &New);
Michael J. Spencer84487f12015-07-24 21:03:07 +000079
Michael J. Spencer1b348a62015-09-04 22:28:10 +000080 std::vector<std::unique_ptr<ArchiveFile>> ArchiveFiles;
81
Rafael Espindola40102eb2015-09-17 18:26:25 +000082 // The order the global symbols are in is not defined. We can use an arbitrary
83 // order, but it has to be reproducible. That is true even when cross linking.
84 // The default hashing of StringRef produces different results on 32 and 64
85 // bit systems so we use a MapVector. That is arbitrary, deterministic but
86 // a bit inefficient.
87 // FIXME: Experiment with passing in a custom hashing or sorting the symbols
88 // once symbol resolution is finished.
89 llvm::MapVector<StringRef, Symbol *> Symtab;
Michael J. Spencer84487f12015-07-24 21:03:07 +000090 llvm::BumpPtrAllocator Alloc;
Rafael Espindola222edc62015-09-03 18:56:20 +000091
92 // The writer needs to infer the machine type from the object files.
93 std::vector<std::unique_ptr<ObjectFileBase>> ObjectFiles;
Rafael Espindolaf98d6d82015-09-03 20:03:54 +000094
95 std::vector<std::unique_ptr<SharedFileBase>> SharedFiles;
Rafael Espindola6a3b5de2015-10-01 19:52:48 +000096 llvm::DenseSet<StringRef> IncludedSoNames;
Michael J. Spencer546c64c2015-09-08 22:34:57 +000097
Michael J. Spencerac5f0482015-09-08 22:51:46 +000098 SymbolBody *EntrySym = nullptr;
Michael J. Spencer84487f12015-07-24 21:03:07 +000099};
100
101} // namespace elf2
102} // namespace lld
103
104#endif