blob: cef2b916b944a3199e53530cf319e154947c724f [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"
Rafael Espindola01205f72015-09-22 18:19:46 +000014#include "Target.h"
Michael J. Spencer84487f12015-07-24 21:03:07 +000015
16using namespace llvm;
Rafael Espindoladaa92a62015-08-31 01:16:19 +000017using namespace llvm::object;
Rafael Espindola01205f72015-09-22 18:19:46 +000018using namespace llvm::ELF;
Michael J. Spencer84487f12015-07-24 21:03:07 +000019
20using namespace lld;
21using namespace lld::elf2;
22
Michael J. Spencerac5f0482015-09-08 22:51:46 +000023SymbolTable::SymbolTable() {}
Michael J. Spencer84487f12015-07-24 21:03:07 +000024
Rafael Espindola67a5da62015-09-17 14:02:10 +000025bool SymbolTable::shouldUseRela() const {
26 ELFKind K = getFirstELF()->getELFKind();
27 return K == ELF64LEKind || K == ELF64BEKind;
28}
29
Rafael Espindola2ffdd4d2015-08-04 14:29:01 +000030void SymbolTable::addFile(std::unique_ptr<InputFile> File) {
Igor Kudrin2696bbe2015-10-01 18:02:21 +000031 if (auto *AF = dyn_cast<ArchiveFile>(File.get())) {
32 File.release();
Michael J. Spencer1b348a62015-09-04 22:28:10 +000033 ArchiveFiles.emplace_back(AF);
Igor Kudrin2696bbe2015-10-01 18:02:21 +000034 if (Config->WholeArchive) {
35 for (MemoryBufferRef &MBRef : AF->getMembers())
36 addFile(createELFFile<ObjectFile>(MBRef));
37 return;
38 }
39 AF->parse();
Michael J. Spencer1b348a62015-09-04 22:28:10 +000040 for (Lazy &Sym : AF->getLazySymbols())
41 addLazy(&Sym);
42 return;
43 }
Rafael Espindola6a3b5de2015-10-01 19:52:48 +000044 if (auto *S = dyn_cast<SharedFileBase>(File.get())) {
45 S->parseSoName();
46 if (!IncludedSoNames.insert(S->getSoName()).second)
47 return;
48 }
Igor Kudrin2696bbe2015-10-01 18:02:21 +000049 File->parse();
50 addELFFile(cast<ELFFileBase>(File.release()));
Michael J. Spencer84487f12015-07-24 21:03:07 +000051}
52
Rafael Espindola1d6063e2015-09-22 21:24:52 +000053static TargetInfo *createTarget(uint16_t EMachine) {
54 switch (EMachine) {
Davide Italianoaabc45b2015-09-27 09:01:28 +000055 case EM_386:
56 return new X86TargetInfo();
Davide Italianocde93362015-09-26 00:32:04 +000057 case EM_AARCH64:
58 return new AArch64TargetInfo();
Davide Italianoaabc45b2015-09-27 09:01:28 +000059 case EM_ARM:
60 return new ARMTargetInfo();
Simon Atanasyan49829a12015-09-29 05:34:03 +000061 case EM_MIPS:
62 return new MipsTargetInfo();
Davide Italianoaabc45b2015-09-27 09:01:28 +000063 case EM_PPC:
64 return new PPCTargetInfo();
Rafael Espindola1d6063e2015-09-22 21:24:52 +000065 case EM_PPC64:
66 return new PPC64TargetInfo();
67 case EM_X86_64:
68 return new X86_64TargetInfo();
Rafael Espindola1d6063e2015-09-22 21:24:52 +000069 }
70 error("Unknown target machine");
71}
72
Denis Protivensky22220d52015-10-05 09:43:57 +000073void SymbolTable::addUndefinedSym(StringRef Name) {
74 switch (getFirstELF()->getELFKind()) {
75 case ELF32LEKind:
76 addUndefinedSym<ELF32LE>(Name);
77 break;
78 case ELF32BEKind:
79 addUndefinedSym<ELF32BE>(Name);
80 break;
81 case ELF64LEKind:
82 addUndefinedSym<ELF64LE>(Name);
83 break;
84 case ELF64BEKind:
85 addUndefinedSym<ELF64BE>(Name);
86 break;
Denis Protivensky1ef7b3f2015-10-07 09:13:03 +000087 default:
88 llvm_unreachable("Invalid kind");
Denis Protivensky22220d52015-10-05 09:43:57 +000089 }
90}
91
92template <class ELFT> void SymbolTable::addUndefinedSym(StringRef Name) {
Rui Ueyama833ce282015-10-08 00:29:00 +000093 resolve<ELFT>(new (Alloc) Undefined<ELFT>(Name, Undefined<ELFT>::Optional));
Denis Protivensky22220d52015-10-05 09:43:57 +000094}
95
Rafael Espindola0e604f92015-09-25 18:56:53 +000096template <class ELFT>
97void SymbolTable::addSyntheticSym(StringRef Name, OutputSection<ELFT> &Section,
98 typename ELFFile<ELFT>::uintX_t Value) {
99 typedef typename DefinedSynthetic<ELFT>::Elf_Sym Elf_Sym;
100 auto ESym = new (Alloc) Elf_Sym;
101 memset(ESym, 0, sizeof(Elf_Sym));
102 ESym->st_value = Value;
103 auto Sym = new (Alloc) DefinedSynthetic<ELFT>(Name, *ESym, Section);
104 resolve<ELFT>(Sym);
105}
106
Rafael Espindola5d413262015-10-01 21:22:26 +0000107template <class ELFT> void SymbolTable::addIgnoredSym(StringRef Name) {
Rafael Espindola5d413262015-10-01 21:22:26 +0000108 auto Sym = new (Alloc)
109 DefinedAbsolute<ELFT>(Name, DefinedAbsolute<ELFT>::IgnoreUndef);
110 resolve<ELFT>(Sym);
111}
112
Rafael Espindola01205f72015-09-22 18:19:46 +0000113template <class ELFT> void SymbolTable::init(uint16_t EMachine) {
Rafael Espindola1d6063e2015-09-22 21:24:52 +0000114 Target.reset(createTarget(EMachine));
Rafael Espindola4340aad2015-09-11 22:42:45 +0000115 if (Config->Shared)
116 return;
Rui Ueyama9d4c6d72015-09-29 16:40:13 +0000117 EntrySym = new (Alloc) Undefined<ELFT>(
118 Config->Entry.empty() ? Target->getDefaultEntry() : Config->Entry,
Rui Ueyama833ce282015-10-08 00:29:00 +0000119 Undefined<ELFT>::Required);
Michael J. Spencer546c64c2015-09-08 22:34:57 +0000120 resolve<ELFT>(EntrySym);
Rafael Espindolad27adc42e2015-09-24 13:34:01 +0000121
122 // In the assembly for 32 bit x86 the _GLOBAL_OFFSET_TABLE_ symbol is magical
123 // and is used to produce a R_386_GOTPC relocation.
124 // The R_386_GOTPC relocation value doesn't actually depend on the
125 // symbol value, so it could use an index of STN_UNDEF which, according to the
126 // spec, means the symbol value is 0.
127 // Unfortunately both gas and MC keep the _GLOBAL_OFFSET_TABLE_ symbol in
128 // the object file.
129 // The situation is even stranger on x86_64 where the assembly doesn't
130 // need the magical symbol, but gas still puts _GLOBAL_OFFSET_TABLE_ as
131 // an undefined symbol in the .o files.
132 // Given that the symbol is effectively unused, we just create a dummy
133 // hidden one to avoid the undefined symbol error.
Rafael Espindola5d413262015-10-01 21:22:26 +0000134 addIgnoredSym<ELFT>("_GLOBAL_OFFSET_TABLE_");
Rafael Espindolaf7d45f02015-08-31 01:46:20 +0000135}
136
Rafael Espindola824d1a92015-09-04 00:09:43 +0000137template <class ELFT> void SymbolTable::addELFFile(ELFFileBase *File) {
Rafael Espindolab90582db2015-10-06 15:03:52 +0000138 const ELFFileBase *Old = getFirstELF();
Rafael Espindolab90582db2015-10-06 15:03:52 +0000139 if (auto *O = dyn_cast<ObjectFileBase>(File))
140 ObjectFiles.emplace_back(O);
141 else if (auto *S = dyn_cast<SharedFile<ELFT>>(File))
142 SharedFiles.emplace_back(S);
143
144 if (!Old)
Rafael Espindola01205f72015-09-22 18:19:46 +0000145 init<ELFT>(File->getEMachine());
Rafael Espindola3c9cb4b2015-08-05 12:03:34 +0000146
Rafael Espindolaf98d6d82015-09-03 20:03:54 +0000147 if (auto *O = dyn_cast<ObjectFileBase>(File)) {
Rafael Espindola824d1a92015-09-04 00:09:43 +0000148 for (SymbolBody *Body : O->getSymbols())
149 resolve<ELFT>(Body);
Rafael Espindoladaa92a62015-08-31 01:16:19 +0000150 }
Rafael Espindolaf98d6d82015-09-03 20:03:54 +0000151
Rafael Espindola18173d42015-09-08 15:50:05 +0000152 if (auto *S = dyn_cast<SharedFile<ELFT>>(File)) {
Rafael Espindola18173d42015-09-08 15:50:05 +0000153 for (SharedSymbol<ELFT> &Body : S->getSharedSymbols())
154 resolve<ELFT>(&Body);
155 }
Michael J. Spencer84487f12015-07-24 21:03:07 +0000156}
157
Rafael Espindola824d1a92015-09-04 00:09:43 +0000158void SymbolTable::addELFFile(ELFFileBase *File) {
159 switch (File->getELFKind()) {
Rui Ueyamad5004e12015-09-09 18:02:23 +0000160 case ELF32LEKind:
161 addELFFile<ELF32LE>(File);
162 break;
163 case ELF32BEKind:
164 addELFFile<ELF32BE>(File);
165 break;
166 case ELF64LEKind:
167 addELFFile<ELF64LE>(File);
168 break;
169 case ELF64BEKind:
170 addELFFile<ELF64BE>(File);
171 break;
Denis Protivensky1ef7b3f2015-10-07 09:13:03 +0000172 default:
173 llvm_unreachable("Invalid kind");
Rafael Espindola824d1a92015-09-04 00:09:43 +0000174 }
175}
176
Rafael Espindola1a49e582015-09-23 14:10:24 +0000177template <class ELFT>
Igor Kudrin65bddea2015-10-09 09:58:39 +0000178void SymbolTable::reportConflict(const Twine &Message, const SymbolBody &Old,
179 const SymbolBody &New, bool Warning) {
Rafael Espindola1a49e582015-09-23 14:10:24 +0000180 typedef typename ELFFile<ELFT>::Elf_Sym Elf_Sym;
181 typedef typename ELFFile<ELFT>::Elf_Sym_Range Elf_Sym_Range;
182
183 const Elf_Sym &OldE = cast<ELFSymbolBody<ELFT>>(Old).Sym;
184 const Elf_Sym &NewE = cast<ELFSymbolBody<ELFT>>(New).Sym;
185 ELFFileBase *OldFile = nullptr;
186 ELFFileBase *NewFile = nullptr;
187
188 for (const std::unique_ptr<ObjectFileBase> &F : ObjectFiles) {
189 const auto &File = cast<ObjectFile<ELFT>>(*F);
Rafael Espindolae1901cc2015-09-24 15:11:50 +0000190 Elf_Sym_Range Syms = File.getObj().symbols(File.getSymbolTable());
Rafael Espindola1a49e582015-09-23 14:10:24 +0000191 if (&OldE > Syms.begin() && &OldE < Syms.end())
192 OldFile = F.get();
193 if (&NewE > Syms.begin() && &NewE < Syms.end())
194 NewFile = F.get();
195 }
196
Igor Kudrin65bddea2015-10-09 09:58:39 +0000197 std::string Msg = (Message + ": " + Old.getName() + " in " +
Rafael Espindola4b2ca852015-09-28 20:30:11 +0000198 OldFile->getName() + " and " + NewFile->getName())
199 .str();
Igor Kudrin65bddea2015-10-09 09:58:39 +0000200 if (Warning)
Rafael Espindola4b2ca852015-09-28 20:30:11 +0000201 warning(Msg);
202 else
203 error(Msg);
Rafael Espindola1a49e582015-09-23 14:10:24 +0000204}
205
Michael J. Spencer84487f12015-07-24 21:03:07 +0000206// This function resolves conflicts if there's an existing symbol with
207// the same name. Decisions are made based on symbol type.
Rafael Espindoladaa92a62015-08-31 01:16:19 +0000208template <class ELFT> void SymbolTable::resolve(SymbolBody *New) {
Michael J. Spencer1b348a62015-09-04 22:28:10 +0000209 Symbol *Sym = insert(New);
210 if (Sym->Body == New)
211 return;
212
213 SymbolBody *Existing = Sym->Body;
214
215 if (Lazy *L = dyn_cast<Lazy>(Existing)) {
216 if (New->isUndefined()) {
Rafael Espindola85a6e0f2015-10-06 15:18:50 +0000217 if (New->isWeak()) {
218 // See the explanation in SymbolTable::addLazy
219 L->setUsedInRegularObj();
220 L->setWeak();
221 return;
222 }
Michael J. Spencer1b348a62015-09-04 22:28:10 +0000223 addMemberFile(L);
224 return;
225 }
226
227 // Found a definition for something also in an archive. Ignore the archive
228 // definition.
229 Sym->Body = New;
230 return;
231 }
232
Igor Kudrin65bddea2015-10-09 09:58:39 +0000233 if (New->isTLS() != Existing->isTLS())
234 reportConflict<ELFT>("TLS attribute mismatch for symbol", *Existing, *New,
235 false);
236
Michael J. Spencer1b348a62015-09-04 22:28:10 +0000237 // compare() returns -1, 0, or 1 if the lhs symbol is less preferable,
238 // equivalent (conflicting), or more preferable, respectively.
239 int comp = Existing->compare<ELFT>(New);
240 if (comp < 0)
241 Sym->Body = New;
Rafael Espindola1a49e582015-09-23 14:10:24 +0000242 else if (comp == 0)
Igor Kudrin65bddea2015-10-09 09:58:39 +0000243 reportConflict<ELFT>("duplicate symbol", *Existing, *New,
244 Config->AllowMultipleDefinition);
Michael J. Spencer1b348a62015-09-04 22:28:10 +0000245}
246
247Symbol *SymbolTable::insert(SymbolBody *New) {
Michael J. Spencer84487f12015-07-24 21:03:07 +0000248 // Find an existing Symbol or create and insert a new one.
249 StringRef Name = New->getName();
250 Symbol *&Sym = Symtab[Name];
251 if (!Sym) {
252 Sym = new (Alloc) Symbol(New);
253 New->setBackref(Sym);
Michael J. Spencer1b348a62015-09-04 22:28:10 +0000254 return Sym;
Michael J. Spencer84487f12015-07-24 21:03:07 +0000255 }
256 New->setBackref(Sym);
Michael J. Spencer1b348a62015-09-04 22:28:10 +0000257 return Sym;
258}
Michael J. Spencer84487f12015-07-24 21:03:07 +0000259
Michael J. Spencer1b348a62015-09-04 22:28:10 +0000260void SymbolTable::addLazy(Lazy *New) {
261 Symbol *Sym = insert(New);
262 if (Sym->Body == New)
263 return;
Michael J. Spencer84487f12015-07-24 21:03:07 +0000264 SymbolBody *Existing = Sym->Body;
Rafael Espindola8614c562015-10-06 14:33:58 +0000265 if (Existing->isDefined() || Existing->isLazy())
Michael J. Spencer1b348a62015-09-04 22:28:10 +0000266 return;
267 Sym->Body = New;
268 assert(Existing->isUndefined() && "Unexpected symbol kind.");
Rafael Espindola8614c562015-10-06 14:33:58 +0000269
270 // Weak undefined symbols should not fetch members from archives.
271 // If we were to keep old symbol we would not know that an archive member was
272 // available if a strong undefined symbol shows up afterwards in the link.
273 // If a strong undefined symbol never shows up, this lazy symbol will
274 // get to the end of the link and must be treated as the weak undefined one.
275 // We set UsedInRegularObj in a similar way to what is done with shared
276 // symbols and mark it as weak to reduce how many special cases are needed.
277 if (Existing->isWeak()) {
278 New->setUsedInRegularObj();
279 New->setWeak();
280 return;
281 }
Michael J. Spencer1b348a62015-09-04 22:28:10 +0000282 addMemberFile(New);
283}
284
285void SymbolTable::addMemberFile(Lazy *Body) {
286 std::unique_ptr<InputFile> File = Body->getMember();
287
288 // getMember returns nullptr if the member was already read from the library.
289 if (!File)
290 return;
291
292 addFile(std::move(File));
Michael J. Spencer84487f12015-07-24 21:03:07 +0000293}
Rafael Espindola0e604f92015-09-25 18:56:53 +0000294
295namespace lld {
296namespace elf2 {
Rafael Espindolad31088b2015-10-01 21:18:37 +0000297template void SymbolTable::addSyntheticSym(StringRef, OutputSection<ELF32LE> &,
298 ELFFile<ELF32LE>::uintX_t);
299template void SymbolTable::addSyntheticSym(StringRef, OutputSection<ELF32BE> &,
300 ELFFile<ELF32BE>::uintX_t);
301template void SymbolTable::addSyntheticSym(StringRef, OutputSection<ELF64LE> &,
302 ELFFile<ELF64LE>::uintX_t);
303template void SymbolTable::addSyntheticSym(StringRef, OutputSection<ELF64BE> &,
304 ELFFile<ELF64BE>::uintX_t);
Rafael Espindola5d413262015-10-01 21:22:26 +0000305
306template void SymbolTable::addIgnoredSym<ELF32LE>(StringRef);
307template void SymbolTable::addIgnoredSym<ELF32BE>(StringRef);
308template void SymbolTable::addIgnoredSym<ELF64LE>(StringRef);
309template void SymbolTable::addIgnoredSym<ELF64BE>(StringRef);
Rafael Espindola0e604f92015-09-25 18:56:53 +0000310}
311}