Rafael Espindola | beee25e | 2015-08-14 14:12:54 +0000 | [diff] [blame] | 1 | //===- SymbolTable.h --------------------------------------------*- C++ -*-===// |
Michael J. Spencer | 84487f1 | 2015-07-24 21:03:07 +0000 | [diff] [blame] | 2 | // |
| 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 Espindola | 40102eb | 2015-09-17 18:26:25 +0000 | [diff] [blame] | 14 | #include "llvm/ADT/MapVector.h" |
Michael J. Spencer | 84487f1 | 2015-07-24 21:03:07 +0000 | [diff] [blame] | 15 | |
Rafael Espindola | 9f77ef0 | 2016-02-12 20:54:57 +0000 | [diff] [blame] | 16 | namespace llvm { |
| 17 | class Module; |
| 18 | } |
| 19 | |
Michael J. Spencer | 84487f1 | 2015-07-24 21:03:07 +0000 | [diff] [blame] | 20 | namespace lld { |
Rafael Espindola | e0df00b | 2016-02-28 00:25:54 +0000 | [diff] [blame^] | 21 | namespace elf { |
Rui Ueyama | c5b9512 | 2015-12-16 23:23:14 +0000 | [diff] [blame] | 22 | class Lazy; |
Rui Ueyama | c5b9512 | 2015-12-16 23:23:14 +0000 | [diff] [blame] | 23 | template <class ELFT> class OutputSectionBase; |
Rafael Espindola | 5d7593b | 2015-12-22 23:00:50 +0000 | [diff] [blame] | 24 | struct Symbol; |
| 25 | class Undefined; |
Michael J. Spencer | 84487f1 | 2015-07-24 21:03:07 +0000 | [diff] [blame] | 26 | |
| 27 | // SymbolTable is a bucket of all known symbols, including defined, |
| 28 | // undefined, or lazy symbols (the last one is symbols in archive |
| 29 | // files whose archive members are not yet loaded). |
| 30 | // |
| 31 | // We put all symbols of all files to a SymbolTable, and the |
| 32 | // SymbolTable selects the "best" symbols if there are name |
| 33 | // conflicts. For example, obviously, a defined symbol is better than |
| 34 | // an undefined symbol. Or, if there's a conflict between a lazy and a |
| 35 | // undefined, it'll read an archive member to read a real definition |
| 36 | // to replace the lazy symbol. The logic is implemented in resolve(). |
Rui Ueyama | 3ce825e | 2015-10-09 21:07:25 +0000 | [diff] [blame] | 37 | template <class ELFT> class SymbolTable { |
Rui Ueyama | 79c7373 | 2016-01-08 21:53:28 +0000 | [diff] [blame] | 38 | typedef typename llvm::object::ELFFile<ELFT>::Elf_Sym Elf_Sym; |
| 39 | typedef typename llvm::object::ELFFile<ELFT>::uintX_t uintX_t; |
| 40 | |
Michael J. Spencer | 84487f1 | 2015-07-24 21:03:07 +0000 | [diff] [blame] | 41 | public: |
Michael J. Spencer | 84487f1 | 2015-07-24 21:03:07 +0000 | [diff] [blame] | 42 | void addFile(std::unique_ptr<InputFile> File); |
Rafael Espindola | 9f77ef0 | 2016-02-12 20:54:57 +0000 | [diff] [blame] | 43 | void addCombinedLtoObject(); |
Michael J. Spencer | 84487f1 | 2015-07-24 21:03:07 +0000 | [diff] [blame] | 44 | |
Rafael Espindola | 40102eb | 2015-09-17 18:26:25 +0000 | [diff] [blame] | 45 | const llvm::MapVector<StringRef, Symbol *> &getSymbols() const { |
Rafael Espindola | 62b81b8 | 2015-08-14 13:07:05 +0000 | [diff] [blame] | 46 | return Symtab; |
| 47 | } |
| 48 | |
Rui Ueyama | 3ce825e | 2015-10-09 21:07:25 +0000 | [diff] [blame] | 49 | const std::vector<std::unique_ptr<ObjectFile<ELFT>>> &getObjectFiles() const { |
Rafael Espindola | 222edc6 | 2015-09-03 18:56:20 +0000 | [diff] [blame] | 50 | return ObjectFiles; |
| 51 | } |
| 52 | |
Rui Ueyama | 3ce825e | 2015-10-09 21:07:25 +0000 | [diff] [blame] | 53 | const std::vector<std::unique_ptr<SharedFile<ELFT>>> &getSharedFiles() const { |
Rafael Espindola | 740fafe | 2015-09-08 19:43:27 +0000 | [diff] [blame] | 54 | return SharedFiles; |
| 55 | } |
| 56 | |
Rui Ueyama | ff77768 | 2015-10-09 21:12:40 +0000 | [diff] [blame] | 57 | SymbolBody *addUndefined(StringRef Name); |
| 58 | SymbolBody *addUndefinedOpt(StringRef Name); |
Rui Ueyama | 79c7373 | 2016-01-08 21:53:28 +0000 | [diff] [blame] | 59 | SymbolBody *addAbsolute(StringRef Name, Elf_Sym &ESym); |
| 60 | SymbolBody *addSynthetic(StringRef Name, OutputSectionBase<ELFT> &Section, |
| 61 | uintX_t Value); |
Rui Ueyama | dd7d998 | 2015-12-16 22:31:14 +0000 | [diff] [blame] | 62 | SymbolBody *addIgnored(StringRef Name); |
Rui Ueyama | 79c7373 | 2016-01-08 21:53:28 +0000 | [diff] [blame] | 63 | |
Rui Ueyama | 93bfee5 | 2015-10-13 18:10:33 +0000 | [diff] [blame] | 64 | void scanShlibUndefined(); |
Rui Ueyama | c4aaed9 | 2015-10-22 18:49:53 +0000 | [diff] [blame] | 65 | SymbolBody *find(StringRef Name); |
Rui Ueyama | deb1540 | 2016-01-07 17:20:07 +0000 | [diff] [blame] | 66 | void wrap(StringRef Name); |
Rafael Espindola | 18f0950 | 2016-02-26 21:49:38 +0000 | [diff] [blame] | 67 | InputFile *findFile(SymbolBody *B); |
Rafael Espindola | 5d41326 | 2015-10-01 21:22:26 +0000 | [diff] [blame] | 68 | |
Michael J. Spencer | 84487f1 | 2015-07-24 21:03:07 +0000 | [diff] [blame] | 69 | private: |
Michael J. Spencer | 1b348a6 | 2015-09-04 22:28:10 +0000 | [diff] [blame] | 70 | Symbol *insert(SymbolBody *New); |
Michael J. Spencer | 1b348a6 | 2015-09-04 22:28:10 +0000 | [diff] [blame] | 71 | void addLazy(Lazy *New); |
Rafael Espindola | 5d7593b | 2015-12-22 23:00:50 +0000 | [diff] [blame] | 72 | void addMemberFile(Undefined *Undef, Lazy *L); |
Rui Ueyama | 3ce825e | 2015-10-09 21:07:25 +0000 | [diff] [blame] | 73 | void resolve(SymbolBody *Body); |
Rafael Espindola | 9f77ef0 | 2016-02-12 20:54:57 +0000 | [diff] [blame] | 74 | std::unique_ptr<InputFile> codegen(llvm::Module &M); |
Rui Ueyama | f090401 | 2015-12-16 22:26:45 +0000 | [diff] [blame] | 75 | std::string conflictMsg(SymbolBody *Old, SymbolBody *New); |
Michael J. Spencer | 84487f1 | 2015-07-24 21:03:07 +0000 | [diff] [blame] | 76 | |
Rafael Espindola | 9f77ef0 | 2016-02-12 20:54:57 +0000 | [diff] [blame] | 77 | SmallString<0> OwningLTOData; |
| 78 | std::unique_ptr<MemoryBuffer> LtoBuffer; |
| 79 | ObjectFile<ELFT> *createCombinedLtoObject(); |
| 80 | |
Rafael Espindola | 40102eb | 2015-09-17 18:26:25 +0000 | [diff] [blame] | 81 | // The order the global symbols are in is not defined. We can use an arbitrary |
| 82 | // order, but it has to be reproducible. That is true even when cross linking. |
| 83 | // The default hashing of StringRef produces different results on 32 and 64 |
| 84 | // bit systems so we use a MapVector. That is arbitrary, deterministic but |
| 85 | // a bit inefficient. |
| 86 | // FIXME: Experiment with passing in a custom hashing or sorting the symbols |
| 87 | // once symbol resolution is finished. |
| 88 | llvm::MapVector<StringRef, Symbol *> Symtab; |
Michael J. Spencer | 84487f1 | 2015-07-24 21:03:07 +0000 | [diff] [blame] | 89 | llvm::BumpPtrAllocator Alloc; |
Rafael Espindola | 222edc6 | 2015-09-03 18:56:20 +0000 | [diff] [blame] | 90 | |
Rui Ueyama | 683564e | 2016-01-08 22:14:15 +0000 | [diff] [blame] | 91 | // Comdat groups define "link once" sections. If two comdat groups have the |
| 92 | // same name, only one of them is linked, and the other is ignored. This set |
| 93 | // is used to uniquify them. |
Rui Ueyama | 52d3b67 | 2016-01-06 02:06:33 +0000 | [diff] [blame] | 94 | llvm::DenseSet<StringRef> ComdatGroups; |
Rafael Espindola | 444576d | 2015-10-09 19:25:07 +0000 | [diff] [blame] | 95 | |
Rui Ueyama | 52c7c5f | 2016-01-08 22:20:00 +0000 | [diff] [blame] | 96 | // The symbol table owns all file objects. |
| 97 | std::vector<std::unique_ptr<ArchiveFile>> ArchiveFiles; |
Rui Ueyama | 3ce825e | 2015-10-09 21:07:25 +0000 | [diff] [blame] | 98 | std::vector<std::unique_ptr<ObjectFile<ELFT>>> ObjectFiles; |
Rui Ueyama | 3ce825e | 2015-10-09 21:07:25 +0000 | [diff] [blame] | 99 | std::vector<std::unique_ptr<SharedFile<ELFT>>> SharedFiles; |
Rafael Espindola | 9f77ef0 | 2016-02-12 20:54:57 +0000 | [diff] [blame] | 100 | std::vector<std::unique_ptr<BitcodeFile>> BitcodeFiles; |
Rui Ueyama | 683564e | 2016-01-08 22:14:15 +0000 | [diff] [blame] | 101 | |
| 102 | // Set of .so files to not link the same shared object file more than once. |
Rui Ueyama | 131e0ff | 2016-01-08 22:17:42 +0000 | [diff] [blame] | 103 | llvm::DenseSet<StringRef> SoNames; |
Michael J. Spencer | 84487f1 | 2015-07-24 21:03:07 +0000 | [diff] [blame] | 104 | }; |
| 105 | |
Rafael Espindola | e0df00b | 2016-02-28 00:25:54 +0000 | [diff] [blame^] | 106 | } // namespace elf |
Michael J. Spencer | 84487f1 | 2015-07-24 21:03:07 +0000 | [diff] [blame] | 107 | } // namespace lld |
| 108 | |
| 109 | #endif |