blob: 356c9e40ccaea91e4d75f5e9d195e1002635af3e [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 Ueyamab4731a52015-07-29 16:30:40 +000014#include "llvm/ADT/DenseMap.h"
15#include "llvm/ADT/DenseMapInfo.h"
Michael J. Spencer84487f12015-07-24 21:03:07 +000016
17namespace lld {
18namespace elf2 {
Michael J. Spencer84487f12015-07-24 21:03:07 +000019struct Symbol;
20
21// SymbolTable is a bucket of all known symbols, including defined,
22// undefined, or lazy symbols (the last one is symbols in archive
23// files whose archive members are not yet loaded).
24//
25// We put all symbols of all files to a SymbolTable, and the
26// SymbolTable selects the "best" symbols if there are name
27// conflicts. For example, obviously, a defined symbol is better than
28// an undefined symbol. Or, if there's a conflict between a lazy and a
29// undefined, it'll read an archive member to read a real definition
30// to replace the lazy symbol. The logic is implemented in resolve().
Rafael Espindola2ffdd4d2015-08-04 14:29:01 +000031class SymbolTable {
Michael J. Spencer84487f12015-07-24 21:03:07 +000032public:
33 SymbolTable();
34
35 void addFile(std::unique_ptr<InputFile> File);
36
Rafael Espindolaf98d6d82015-09-03 20:03:54 +000037 const ELFFileBase *getFirstELF() const {
Rafael Espindola8aeb13f2015-09-03 19:13:13 +000038 if (!ObjectFiles.empty())
39 return ObjectFiles[0].get();
Rafael Espindolaf98d6d82015-09-03 20:03:54 +000040 if (!SharedFiles.empty())
41 return SharedFiles[0].get();
Rafael Espindola8aeb13f2015-09-03 19:13:13 +000042 return nullptr;
43 }
44
Rafael Espindola62b81b82015-08-14 13:07:05 +000045 const llvm::DenseMap<StringRef, Symbol *> &getSymbols() const {
46 return Symtab;
47 }
48
Rafael Espindola222edc62015-09-03 18:56:20 +000049 const std::vector<std::unique_ptr<ObjectFileBase>> &getObjectFiles() const {
50 return ObjectFiles;
51 }
52
Rafael Espindola740fafe2015-09-08 19:43:27 +000053 const std::vector<std::unique_ptr<SharedFileBase>> &getSharedFiles() const {
54 return SharedFiles;
55 }
56
Michael J. Spencer546c64c2015-09-08 22:34:57 +000057 SymbolBody *getEntrySym() const {
58 return EntrySym;
59 }
60
Michael J. Spencer84487f12015-07-24 21:03:07 +000061private:
Michael J. Spencer1b348a62015-09-04 22:28:10 +000062 Symbol *insert(SymbolBody *New);
Rafael Espindola824d1a92015-09-04 00:09:43 +000063 template <class ELFT> void addELFFile(ELFFileBase *File);
Rafael Espindolaf98d6d82015-09-03 20:03:54 +000064 void addELFFile(ELFFileBase *File);
Michael J. Spencer1b348a62015-09-04 22:28:10 +000065 void addLazy(Lazy *New);
66 void addMemberFile(Lazy *Body);
Michael J. Spencer84487f12015-07-24 21:03:07 +000067
Rafael Espindolaf7d45f02015-08-31 01:46:20 +000068 template <class ELFT> void init();
Rafael Espindoladaa92a62015-08-31 01:16:19 +000069 template <class ELFT> void resolve(SymbolBody *Body);
Michael J. Spencer84487f12015-07-24 21:03:07 +000070
Michael J. Spencer1b348a62015-09-04 22:28:10 +000071 std::vector<std::unique_ptr<ArchiveFile>> ArchiveFiles;
72
Rui Ueyamab4731a52015-07-29 16:30:40 +000073 llvm::DenseMap<StringRef, Symbol *> Symtab;
Michael J. Spencer84487f12015-07-24 21:03:07 +000074 llvm::BumpPtrAllocator Alloc;
Rafael Espindola222edc62015-09-03 18:56:20 +000075
76 // The writer needs to infer the machine type from the object files.
77 std::vector<std::unique_ptr<ObjectFileBase>> ObjectFiles;
Rafael Espindolaf98d6d82015-09-03 20:03:54 +000078
79 std::vector<std::unique_ptr<SharedFileBase>> SharedFiles;
Michael J. Spencer546c64c2015-09-08 22:34:57 +000080
81 SymbolBody *EntrySym;
Michael J. Spencer84487f12015-07-24 21:03:07 +000082};
83
84} // namespace elf2
85} // namespace lld
86
87#endif