blob: e3ed53a45d2ec2d4e3ecf20c7c35ad38f143be4a [file] [log] [blame]
Michael J. Spencer84487f12015-07-24 21:03:07 +00001//===- SymbolTable.cpp ----------------------------------------------------===//
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#include "SymbolTable.h"
Rafael Espindola4340aad2015-09-11 22:42:45 +000011#include "Config.h"
Rafael Espindola192e1fa2015-08-06 15:08:23 +000012#include "Error.h"
Michael J. Spencer84487f12015-07-24 21:03:07 +000013#include "Symbols.h"
14
15using namespace llvm;
Rafael Espindoladaa92a62015-08-31 01:16:19 +000016using namespace llvm::object;
Rafael Espindola01205f72015-09-22 18:19:46 +000017using namespace llvm::ELF;
Michael J. Spencer84487f12015-07-24 21:03:07 +000018
19using namespace lld;
20using namespace lld::elf2;
21
Rui Ueyama3ce825e2015-10-09 21:07:25 +000022template <class ELFT> SymbolTable<ELFT>::SymbolTable() {}
Michael J. Spencer84487f12015-07-24 21:03:07 +000023
Rui Ueyama3ce825e2015-10-09 21:07:25 +000024template <class ELFT> bool SymbolTable<ELFT>::shouldUseRela() const {
Rafael Espindolab9ca7bb2015-10-12 11:52:31 +000025 ELFKind K = cast<ELFFileBase<ELFT>>(Config->FirstElf)->getELFKind();
Rafael Espindola67a5da62015-09-17 14:02:10 +000026 return K == ELF64LEKind || K == ELF64BEKind;
27}
28
Rui Ueyama3ce825e2015-10-09 21:07:25 +000029template <class ELFT>
30void SymbolTable<ELFT>::addFile(std::unique_ptr<InputFile> File) {
Rafael Espindola525914d2015-10-11 03:36:49 +000031
Rafael Espindolaaf707642015-10-12 01:55:32 +000032 if (auto *E = dyn_cast<ELFFileBase<ELFT>>(File.get())) {
Rafael Espindola525914d2015-10-11 03:36:49 +000033 if (E->getELFKind() != Config->ElfKind ||
34 E->getEMachine() != Config->EMachine) {
35 StringRef A = E->getName();
36 StringRef B = Config->Emulation;
37 if (B.empty())
Rafael Espindola9afbac42015-10-11 20:19:20 +000038 B = Config->FirstElf->getName();
Rafael Espindola525914d2015-10-11 03:36:49 +000039 error(A + " is incompatible with " + B);
40 }
41 }
42
Igor Kudrin2696bbe2015-10-01 18:02:21 +000043 if (auto *AF = dyn_cast<ArchiveFile>(File.get())) {
Rui Ueyama3ce825e2015-10-09 21:07:25 +000044 ArchiveFiles.emplace_back(std::move(File));
Igor Kudrin2696bbe2015-10-01 18:02:21 +000045 AF->parse();
Michael J. Spencer1b348a62015-09-04 22:28:10 +000046 for (Lazy &Sym : AF->getLazySymbols())
47 addLazy(&Sym);
48 return;
49 }
Rafael Espindoladfce5a22015-10-12 02:22:58 +000050 if (auto *S = dyn_cast<SharedFile<ELFT>>(File.get())) {
Rafael Espindola6a3b5de2015-10-01 19:52:48 +000051 S->parseSoName();
52 if (!IncludedSoNames.insert(S->getSoName()).second)
53 return;
Rafael Espindola444576d2015-10-09 19:25:07 +000054 S->parse();
55 } else {
Rafael Espindoladfce5a22015-10-12 02:22:58 +000056 cast<ObjectFile<ELFT>>(File.get())->parse(Comdats);
Rafael Espindola6a3b5de2015-10-01 19:52:48 +000057 }
Rafael Espindolaaf707642015-10-12 01:55:32 +000058 addELFFile(cast<ELFFileBase<ELFT>>(File.release()));
Michael J. Spencer84487f12015-07-24 21:03:07 +000059}
60
Rui Ueyamaff777682015-10-09 21:12:40 +000061template <class ELFT>
62SymbolBody *SymbolTable<ELFT>::addUndefined(StringRef Name) {
63 auto *Sym = new (Alloc) Undefined<ELFT>(Name, Undefined<ELFT>::Required);
64 resolve(Sym);
65 return Sym;
Rafael Espindola1d6063e2015-09-22 21:24:52 +000066}
67
Rui Ueyamaff777682015-10-09 21:12:40 +000068template <class ELFT>
69SymbolBody *SymbolTable<ELFT>::addUndefinedOpt(StringRef Name) {
70 auto *Sym = new (Alloc) Undefined<ELFT>(Name, Undefined<ELFT>::Optional);
71 resolve(Sym);
72 return Sym;
Denis Protivensky22220d52015-10-05 09:43:57 +000073}
74
Rafael Espindola0e604f92015-09-25 18:56:53 +000075template <class ELFT>
Rui Ueyama3ce825e2015-10-09 21:07:25 +000076void SymbolTable<ELFT>::addSyntheticSym(StringRef Name,
77 OutputSection<ELFT> &Section,
78 typename ELFFile<ELFT>::uintX_t Value) {
Rafael Espindola0e604f92015-09-25 18:56:53 +000079 typedef typename DefinedSynthetic<ELFT>::Elf_Sym Elf_Sym;
80 auto ESym = new (Alloc) Elf_Sym;
81 memset(ESym, 0, sizeof(Elf_Sym));
82 ESym->st_value = Value;
83 auto Sym = new (Alloc) DefinedSynthetic<ELFT>(Name, *ESym, Section);
Rui Ueyama3ce825e2015-10-09 21:07:25 +000084 resolve(Sym);
Rafael Espindola0e604f92015-09-25 18:56:53 +000085}
86
Rui Ueyama3ce825e2015-10-09 21:07:25 +000087template <class ELFT> void SymbolTable<ELFT>::addIgnoredSym(StringRef Name) {
Rafael Espindola5d413262015-10-01 21:22:26 +000088 auto Sym = new (Alloc)
89 DefinedAbsolute<ELFT>(Name, DefinedAbsolute<ELFT>::IgnoreUndef);
Rui Ueyama3ce825e2015-10-09 21:07:25 +000090 resolve(Sym);
Rafael Espindola5d413262015-10-01 21:22:26 +000091}
92
Rafael Espindolaaf707642015-10-12 01:55:32 +000093template <class ELFT>
94void SymbolTable<ELFT>::addELFFile(ELFFileBase<ELFT> *File) {
Rui Ueyama3ce825e2015-10-09 21:07:25 +000095 if (auto *O = dyn_cast<ObjectFile<ELFT>>(File))
Rafael Espindolab90582db2015-10-06 15:03:52 +000096 ObjectFiles.emplace_back(O);
97 else if (auto *S = dyn_cast<SharedFile<ELFT>>(File))
98 SharedFiles.emplace_back(S);
99
Rafael Espindoladfce5a22015-10-12 02:22:58 +0000100 if (auto *O = dyn_cast<ObjectFile<ELFT>>(File)) {
Rafael Espindola824d1a92015-09-04 00:09:43 +0000101 for (SymbolBody *Body : O->getSymbols())
Rui Ueyama3ce825e2015-10-09 21:07:25 +0000102 resolve(Body);
Rafael Espindoladaa92a62015-08-31 01:16:19 +0000103 }
Rafael Espindolaf98d6d82015-09-03 20:03:54 +0000104
Rafael Espindola18173d42015-09-08 15:50:05 +0000105 if (auto *S = dyn_cast<SharedFile<ELFT>>(File)) {
Rafael Espindola18173d42015-09-08 15:50:05 +0000106 for (SharedSymbol<ELFT> &Body : S->getSharedSymbols())
Rui Ueyama3ce825e2015-10-09 21:07:25 +0000107 resolve(&Body);
Rafael Espindola824d1a92015-09-04 00:09:43 +0000108 }
109}
110
Rafael Espindola1a49e582015-09-23 14:10:24 +0000111template <class ELFT>
Rui Ueyama3ce825e2015-10-09 21:07:25 +0000112void SymbolTable<ELFT>::reportConflict(const Twine &Message,
113 const SymbolBody &Old,
114 const SymbolBody &New, bool Warning) {
Rafael Espindola1a49e582015-09-23 14:10:24 +0000115 typedef typename ELFFile<ELFT>::Elf_Sym Elf_Sym;
116 typedef typename ELFFile<ELFT>::Elf_Sym_Range Elf_Sym_Range;
117
118 const Elf_Sym &OldE = cast<ELFSymbolBody<ELFT>>(Old).Sym;
119 const Elf_Sym &NewE = cast<ELFSymbolBody<ELFT>>(New).Sym;
Rafael Espindolaaf707642015-10-12 01:55:32 +0000120 ELFFileBase<ELFT> *OldFile = nullptr;
121 ELFFileBase<ELFT> *NewFile = nullptr;
Rafael Espindola1a49e582015-09-23 14:10:24 +0000122
Rui Ueyama3ce825e2015-10-09 21:07:25 +0000123 for (const std::unique_ptr<ObjectFile<ELFT>> &File : ObjectFiles) {
124 Elf_Sym_Range Syms = File->getObj().symbols(File->getSymbolTable());
Rafael Espindola1a49e582015-09-23 14:10:24 +0000125 if (&OldE > Syms.begin() && &OldE < Syms.end())
Rui Ueyama3ce825e2015-10-09 21:07:25 +0000126 OldFile = File.get();
Rafael Espindola1a49e582015-09-23 14:10:24 +0000127 if (&NewE > Syms.begin() && &NewE < Syms.end())
Rui Ueyama3ce825e2015-10-09 21:07:25 +0000128 NewFile = File.get();
Rafael Espindola1a49e582015-09-23 14:10:24 +0000129 }
130
Igor Kudrin65bddea2015-10-09 09:58:39 +0000131 std::string Msg = (Message + ": " + Old.getName() + " in " +
Rafael Espindola4b2ca852015-09-28 20:30:11 +0000132 OldFile->getName() + " and " + NewFile->getName())
133 .str();
Igor Kudrin65bddea2015-10-09 09:58:39 +0000134 if (Warning)
Rafael Espindola4b2ca852015-09-28 20:30:11 +0000135 warning(Msg);
136 else
137 error(Msg);
Rafael Espindola1a49e582015-09-23 14:10:24 +0000138}
139
Michael J. Spencer84487f12015-07-24 21:03:07 +0000140// This function resolves conflicts if there's an existing symbol with
141// the same name. Decisions are made based on symbol type.
Rui Ueyama3ce825e2015-10-09 21:07:25 +0000142template <class ELFT> void SymbolTable<ELFT>::resolve(SymbolBody *New) {
Michael J. Spencer1b348a62015-09-04 22:28:10 +0000143 Symbol *Sym = insert(New);
144 if (Sym->Body == New)
145 return;
146
147 SymbolBody *Existing = Sym->Body;
148
149 if (Lazy *L = dyn_cast<Lazy>(Existing)) {
150 if (New->isUndefined()) {
Rafael Espindola85a6e0f2015-10-06 15:18:50 +0000151 if (New->isWeak()) {
152 // See the explanation in SymbolTable::addLazy
153 L->setUsedInRegularObj();
154 L->setWeak();
155 return;
156 }
Michael J. Spencer1b348a62015-09-04 22:28:10 +0000157 addMemberFile(L);
158 return;
159 }
160
161 // Found a definition for something also in an archive. Ignore the archive
162 // definition.
163 Sym->Body = New;
164 return;
165 }
166
Igor Kudrin65bddea2015-10-09 09:58:39 +0000167 if (New->isTLS() != Existing->isTLS())
Rui Ueyama3ce825e2015-10-09 21:07:25 +0000168 reportConflict("TLS attribute mismatch for symbol", *Existing, *New, false);
Igor Kudrin65bddea2015-10-09 09:58:39 +0000169
Michael J. Spencer1b348a62015-09-04 22:28:10 +0000170 // compare() returns -1, 0, or 1 if the lhs symbol is less preferable,
171 // equivalent (conflicting), or more preferable, respectively.
172 int comp = Existing->compare<ELFT>(New);
173 if (comp < 0)
174 Sym->Body = New;
Rafael Espindola1a49e582015-09-23 14:10:24 +0000175 else if (comp == 0)
Rui Ueyama3ce825e2015-10-09 21:07:25 +0000176 reportConflict("duplicate symbol", *Existing, *New,
177 Config->AllowMultipleDefinition);
Michael J. Spencer1b348a62015-09-04 22:28:10 +0000178}
179
Rui Ueyama3ce825e2015-10-09 21:07:25 +0000180template <class ELFT> Symbol *SymbolTable<ELFT>::insert(SymbolBody *New) {
Michael J. Spencer84487f12015-07-24 21:03:07 +0000181 // Find an existing Symbol or create and insert a new one.
182 StringRef Name = New->getName();
183 Symbol *&Sym = Symtab[Name];
184 if (!Sym) {
185 Sym = new (Alloc) Symbol(New);
186 New->setBackref(Sym);
Michael J. Spencer1b348a62015-09-04 22:28:10 +0000187 return Sym;
Michael J. Spencer84487f12015-07-24 21:03:07 +0000188 }
189 New->setBackref(Sym);
Michael J. Spencer1b348a62015-09-04 22:28:10 +0000190 return Sym;
191}
Michael J. Spencer84487f12015-07-24 21:03:07 +0000192
Rui Ueyama3ce825e2015-10-09 21:07:25 +0000193template <class ELFT> void SymbolTable<ELFT>::addLazy(Lazy *New) {
Michael J. Spencer1b348a62015-09-04 22:28:10 +0000194 Symbol *Sym = insert(New);
195 if (Sym->Body == New)
196 return;
Michael J. Spencer84487f12015-07-24 21:03:07 +0000197 SymbolBody *Existing = Sym->Body;
Rafael Espindola8614c562015-10-06 14:33:58 +0000198 if (Existing->isDefined() || Existing->isLazy())
Michael J. Spencer1b348a62015-09-04 22:28:10 +0000199 return;
200 Sym->Body = New;
201 assert(Existing->isUndefined() && "Unexpected symbol kind.");
Rafael Espindola8614c562015-10-06 14:33:58 +0000202
203 // Weak undefined symbols should not fetch members from archives.
204 // If we were to keep old symbol we would not know that an archive member was
205 // available if a strong undefined symbol shows up afterwards in the link.
206 // If a strong undefined symbol never shows up, this lazy symbol will
207 // get to the end of the link and must be treated as the weak undefined one.
208 // We set UsedInRegularObj in a similar way to what is done with shared
209 // symbols and mark it as weak to reduce how many special cases are needed.
210 if (Existing->isWeak()) {
211 New->setUsedInRegularObj();
212 New->setWeak();
213 return;
214 }
Michael J. Spencer1b348a62015-09-04 22:28:10 +0000215 addMemberFile(New);
216}
217
Rui Ueyama3ce825e2015-10-09 21:07:25 +0000218template <class ELFT> void SymbolTable<ELFT>::addMemberFile(Lazy *Body) {
Michael J. Spencer1b348a62015-09-04 22:28:10 +0000219 std::unique_ptr<InputFile> File = Body->getMember();
220
221 // getMember returns nullptr if the member was already read from the library.
222 if (!File)
223 return;
224
225 addFile(std::move(File));
Michael J. Spencer84487f12015-07-24 21:03:07 +0000226}
Rafael Espindola0e604f92015-09-25 18:56:53 +0000227
Rui Ueyama3ce825e2015-10-09 21:07:25 +0000228template class lld::elf2::SymbolTable<ELF32LE>;
229template class lld::elf2::SymbolTable<ELF32BE>;
230template class lld::elf2::SymbolTable<ELF64LE>;
231template class lld::elf2::SymbolTable<ELF64BE>;