blob: 6818d53db8dc1305625c5036241085283ff83bcf [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) {
Rui Ueyama3d451792015-10-12 18:03:21 +000031 checkCompatibility(File);
Rafael Espindola525914d2015-10-11 03:36:49 +000032
Igor Kudrin2696bbe2015-10-01 18:02:21 +000033 if (auto *AF = dyn_cast<ArchiveFile>(File.get())) {
Rui Ueyama3ce825e2015-10-09 21:07:25 +000034 ArchiveFiles.emplace_back(std::move(File));
Igor Kudrin2696bbe2015-10-01 18:02:21 +000035 AF->parse();
Michael J. Spencer1b348a62015-09-04 22:28:10 +000036 for (Lazy &Sym : AF->getLazySymbols())
37 addLazy(&Sym);
38 return;
39 }
Rui Ueyama3d451792015-10-12 18:03:21 +000040
Rafael Espindoladfce5a22015-10-12 02:22:58 +000041 if (auto *S = dyn_cast<SharedFile<ELFT>>(File.get())) {
Rafael Espindola6a3b5de2015-10-01 19:52:48 +000042 S->parseSoName();
43 if (!IncludedSoNames.insert(S->getSoName()).second)
44 return;
Rafael Espindola444576d2015-10-09 19:25:07 +000045 S->parse();
46 } else {
Rafael Espindoladfce5a22015-10-12 02:22:58 +000047 cast<ObjectFile<ELFT>>(File.get())->parse(Comdats);
Rafael Espindola6a3b5de2015-10-01 19:52:48 +000048 }
Rafael Espindolaaf707642015-10-12 01:55:32 +000049 addELFFile(cast<ELFFileBase<ELFT>>(File.release()));
Michael J. Spencer84487f12015-07-24 21:03:07 +000050}
51
Rui Ueyamaff777682015-10-09 21:12:40 +000052template <class ELFT>
53SymbolBody *SymbolTable<ELFT>::addUndefined(StringRef Name) {
54 auto *Sym = new (Alloc) Undefined<ELFT>(Name, Undefined<ELFT>::Required);
55 resolve(Sym);
56 return Sym;
Rafael Espindola1d6063e2015-09-22 21:24:52 +000057}
58
Rui Ueyamaff777682015-10-09 21:12:40 +000059template <class ELFT>
60SymbolBody *SymbolTable<ELFT>::addUndefinedOpt(StringRef Name) {
61 auto *Sym = new (Alloc) Undefined<ELFT>(Name, Undefined<ELFT>::Optional);
62 resolve(Sym);
63 return Sym;
Denis Protivensky22220d52015-10-05 09:43:57 +000064}
65
Rafael Espindola0e604f92015-09-25 18:56:53 +000066template <class ELFT>
Rui Ueyama3ce825e2015-10-09 21:07:25 +000067void SymbolTable<ELFT>::addSyntheticSym(StringRef Name,
68 OutputSection<ELFT> &Section,
69 typename ELFFile<ELFT>::uintX_t Value) {
Rafael Espindola0e604f92015-09-25 18:56:53 +000070 typedef typename DefinedSynthetic<ELFT>::Elf_Sym Elf_Sym;
71 auto ESym = new (Alloc) Elf_Sym;
72 memset(ESym, 0, sizeof(Elf_Sym));
73 ESym->st_value = Value;
74 auto Sym = new (Alloc) DefinedSynthetic<ELFT>(Name, *ESym, Section);
Rui Ueyama3ce825e2015-10-09 21:07:25 +000075 resolve(Sym);
Rafael Espindola0e604f92015-09-25 18:56:53 +000076}
77
Rui Ueyama3ce825e2015-10-09 21:07:25 +000078template <class ELFT> void SymbolTable<ELFT>::addIgnoredSym(StringRef Name) {
Rafael Espindola5d413262015-10-01 21:22:26 +000079 auto Sym = new (Alloc)
80 DefinedAbsolute<ELFT>(Name, DefinedAbsolute<ELFT>::IgnoreUndef);
Rui Ueyama3ce825e2015-10-09 21:07:25 +000081 resolve(Sym);
Rafael Espindola5d413262015-10-01 21:22:26 +000082}
83
Rafael Espindolaaf707642015-10-12 01:55:32 +000084template <class ELFT>
85void SymbolTable<ELFT>::addELFFile(ELFFileBase<ELFT> *File) {
Rui Ueyama3ce825e2015-10-09 21:07:25 +000086 if (auto *O = dyn_cast<ObjectFile<ELFT>>(File))
Rafael Espindolab90582db2015-10-06 15:03:52 +000087 ObjectFiles.emplace_back(O);
88 else if (auto *S = dyn_cast<SharedFile<ELFT>>(File))
89 SharedFiles.emplace_back(S);
90
Rafael Espindoladfce5a22015-10-12 02:22:58 +000091 if (auto *O = dyn_cast<ObjectFile<ELFT>>(File)) {
Rafael Espindola824d1a92015-09-04 00:09:43 +000092 for (SymbolBody *Body : O->getSymbols())
Rui Ueyama3ce825e2015-10-09 21:07:25 +000093 resolve(Body);
Rafael Espindoladaa92a62015-08-31 01:16:19 +000094 }
Rafael Espindolaf98d6d82015-09-03 20:03:54 +000095
Rafael Espindola18173d42015-09-08 15:50:05 +000096 if (auto *S = dyn_cast<SharedFile<ELFT>>(File)) {
Rafael Espindola18173d42015-09-08 15:50:05 +000097 for (SharedSymbol<ELFT> &Body : S->getSharedSymbols())
Rui Ueyama3ce825e2015-10-09 21:07:25 +000098 resolve(&Body);
Rafael Espindola824d1a92015-09-04 00:09:43 +000099 }
100}
101
Rafael Espindola1a49e582015-09-23 14:10:24 +0000102template <class ELFT>
Rui Ueyama3ce825e2015-10-09 21:07:25 +0000103void SymbolTable<ELFT>::reportConflict(const Twine &Message,
104 const SymbolBody &Old,
105 const SymbolBody &New, bool Warning) {
Rafael Espindola1a49e582015-09-23 14:10:24 +0000106 typedef typename ELFFile<ELFT>::Elf_Sym Elf_Sym;
107 typedef typename ELFFile<ELFT>::Elf_Sym_Range Elf_Sym_Range;
108
109 const Elf_Sym &OldE = cast<ELFSymbolBody<ELFT>>(Old).Sym;
110 const Elf_Sym &NewE = cast<ELFSymbolBody<ELFT>>(New).Sym;
Rafael Espindolaaf707642015-10-12 01:55:32 +0000111 ELFFileBase<ELFT> *OldFile = nullptr;
112 ELFFileBase<ELFT> *NewFile = nullptr;
Rafael Espindola1a49e582015-09-23 14:10:24 +0000113
Rui Ueyama3ce825e2015-10-09 21:07:25 +0000114 for (const std::unique_ptr<ObjectFile<ELFT>> &File : ObjectFiles) {
115 Elf_Sym_Range Syms = File->getObj().symbols(File->getSymbolTable());
Rafael Espindola1a49e582015-09-23 14:10:24 +0000116 if (&OldE > Syms.begin() && &OldE < Syms.end())
Rui Ueyama3ce825e2015-10-09 21:07:25 +0000117 OldFile = File.get();
Rafael Espindola1a49e582015-09-23 14:10:24 +0000118 if (&NewE > Syms.begin() && &NewE < Syms.end())
Rui Ueyama3ce825e2015-10-09 21:07:25 +0000119 NewFile = File.get();
Rafael Espindola1a49e582015-09-23 14:10:24 +0000120 }
121
Igor Kudrin65bddea2015-10-09 09:58:39 +0000122 std::string Msg = (Message + ": " + Old.getName() + " in " +
Rafael Espindola4b2ca852015-09-28 20:30:11 +0000123 OldFile->getName() + " and " + NewFile->getName())
124 .str();
Igor Kudrin65bddea2015-10-09 09:58:39 +0000125 if (Warning)
Rafael Espindola4b2ca852015-09-28 20:30:11 +0000126 warning(Msg);
127 else
128 error(Msg);
Rafael Espindola1a49e582015-09-23 14:10:24 +0000129}
130
Michael J. Spencer84487f12015-07-24 21:03:07 +0000131// This function resolves conflicts if there's an existing symbol with
132// the same name. Decisions are made based on symbol type.
Rui Ueyama3ce825e2015-10-09 21:07:25 +0000133template <class ELFT> void SymbolTable<ELFT>::resolve(SymbolBody *New) {
Michael J. Spencer1b348a62015-09-04 22:28:10 +0000134 Symbol *Sym = insert(New);
135 if (Sym->Body == New)
136 return;
137
138 SymbolBody *Existing = Sym->Body;
139
140 if (Lazy *L = dyn_cast<Lazy>(Existing)) {
141 if (New->isUndefined()) {
Rafael Espindola85a6e0f2015-10-06 15:18:50 +0000142 if (New->isWeak()) {
143 // See the explanation in SymbolTable::addLazy
144 L->setUsedInRegularObj();
145 L->setWeak();
146 return;
147 }
Michael J. Spencer1b348a62015-09-04 22:28:10 +0000148 addMemberFile(L);
149 return;
150 }
151
152 // Found a definition for something also in an archive. Ignore the archive
153 // definition.
154 Sym->Body = New;
155 return;
156 }
157
Igor Kudrin65bddea2015-10-09 09:58:39 +0000158 if (New->isTLS() != Existing->isTLS())
Rui Ueyama3ce825e2015-10-09 21:07:25 +0000159 reportConflict("TLS attribute mismatch for symbol", *Existing, *New, false);
Igor Kudrin65bddea2015-10-09 09:58:39 +0000160
Michael J. Spencer1b348a62015-09-04 22:28:10 +0000161 // compare() returns -1, 0, or 1 if the lhs symbol is less preferable,
162 // equivalent (conflicting), or more preferable, respectively.
163 int comp = Existing->compare<ELFT>(New);
164 if (comp < 0)
165 Sym->Body = New;
Rafael Espindola1a49e582015-09-23 14:10:24 +0000166 else if (comp == 0)
Rui Ueyama3ce825e2015-10-09 21:07:25 +0000167 reportConflict("duplicate symbol", *Existing, *New,
168 Config->AllowMultipleDefinition);
Michael J. Spencer1b348a62015-09-04 22:28:10 +0000169}
170
Rui Ueyama3ce825e2015-10-09 21:07:25 +0000171template <class ELFT> Symbol *SymbolTable<ELFT>::insert(SymbolBody *New) {
Michael J. Spencer84487f12015-07-24 21:03:07 +0000172 // Find an existing Symbol or create and insert a new one.
173 StringRef Name = New->getName();
174 Symbol *&Sym = Symtab[Name];
175 if (!Sym) {
176 Sym = new (Alloc) Symbol(New);
177 New->setBackref(Sym);
Michael J. Spencer1b348a62015-09-04 22:28:10 +0000178 return Sym;
Michael J. Spencer84487f12015-07-24 21:03:07 +0000179 }
180 New->setBackref(Sym);
Michael J. Spencer1b348a62015-09-04 22:28:10 +0000181 return Sym;
182}
Michael J. Spencer84487f12015-07-24 21:03:07 +0000183
Rui Ueyama3ce825e2015-10-09 21:07:25 +0000184template <class ELFT> void SymbolTable<ELFT>::addLazy(Lazy *New) {
Michael J. Spencer1b348a62015-09-04 22:28:10 +0000185 Symbol *Sym = insert(New);
186 if (Sym->Body == New)
187 return;
Michael J. Spencer84487f12015-07-24 21:03:07 +0000188 SymbolBody *Existing = Sym->Body;
Rafael Espindola8614c562015-10-06 14:33:58 +0000189 if (Existing->isDefined() || Existing->isLazy())
Michael J. Spencer1b348a62015-09-04 22:28:10 +0000190 return;
191 Sym->Body = New;
192 assert(Existing->isUndefined() && "Unexpected symbol kind.");
Rafael Espindola8614c562015-10-06 14:33:58 +0000193
194 // Weak undefined symbols should not fetch members from archives.
195 // If we were to keep old symbol we would not know that an archive member was
196 // available if a strong undefined symbol shows up afterwards in the link.
197 // If a strong undefined symbol never shows up, this lazy symbol will
198 // get to the end of the link and must be treated as the weak undefined one.
199 // We set UsedInRegularObj in a similar way to what is done with shared
200 // symbols and mark it as weak to reduce how many special cases are needed.
201 if (Existing->isWeak()) {
202 New->setUsedInRegularObj();
203 New->setWeak();
204 return;
205 }
Michael J. Spencer1b348a62015-09-04 22:28:10 +0000206 addMemberFile(New);
207}
208
Rui Ueyama3d451792015-10-12 18:03:21 +0000209template <class ELFT>
210void SymbolTable<ELFT>::checkCompatibility(std::unique_ptr<InputFile> &File) {
211 auto *E = dyn_cast<ELFFileBase<ELFT>>(File.get());
212 if (!E)
213 return;
Rui Ueyamae717a712015-10-13 16:20:50 +0000214 if (E->getELFKind() == Config->EKind && E->getEMachine() == Config->EMachine)
Rui Ueyama3d451792015-10-12 18:03:21 +0000215 return;
216 StringRef A = E->getName();
217 StringRef B = Config->Emulation;
218 if (B.empty())
219 B = Config->FirstElf->getName();
220 error(A + " is incompatible with " + B);
221}
222
Rui Ueyama3ce825e2015-10-09 21:07:25 +0000223template <class ELFT> void SymbolTable<ELFT>::addMemberFile(Lazy *Body) {
Michael J. Spencer1b348a62015-09-04 22:28:10 +0000224 std::unique_ptr<InputFile> File = Body->getMember();
225
226 // getMember returns nullptr if the member was already read from the library.
227 if (!File)
228 return;
229
230 addFile(std::move(File));
Michael J. Spencer84487f12015-07-24 21:03:07 +0000231}
Rafael Espindola0e604f92015-09-25 18:56:53 +0000232
Rui Ueyama3ce825e2015-10-09 21:07:25 +0000233template class lld::elf2::SymbolTable<ELF32LE>;
234template class lld::elf2::SymbolTable<ELF32BE>;
235template class lld::elf2::SymbolTable<ELF64LE>;
236template class lld::elf2::SymbolTable<ELF64BE>;