]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/tools/lld/ELF/Symbols.cpp
Merge llvm, clang, lld and lldb trunk r291012, and resolve conflicts.
[FreeBSD/FreeBSD.git] / contrib / llvm / tools / lld / ELF / Symbols.cpp
1 //===- Symbols.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 "Symbols.h"
11 #include "Error.h"
12 #include "InputFiles.h"
13 #include "InputSection.h"
14 #include "OutputSections.h"
15 #include "Strings.h"
16 #include "SyntheticSections.h"
17 #include "Target.h"
18 #include "Writer.h"
19
20 #include "llvm/ADT/STLExtras.h"
21 #include "llvm/Support/Path.h"
22 #include <cstring>
23
24 using namespace llvm;
25 using namespace llvm::object;
26 using namespace llvm::ELF;
27
28 using namespace lld;
29 using namespace lld::elf;
30
31 template <class ELFT>
32 static typename ELFT::uint getSymVA(const SymbolBody &Body,
33                                     typename ELFT::uint &Addend) {
34   typedef typename ELFT::uint uintX_t;
35
36   switch (Body.kind()) {
37   case SymbolBody::DefinedSyntheticKind: {
38     auto &D = cast<DefinedSynthetic>(Body);
39     const OutputSectionBase *Sec = D.Section;
40     if (!Sec)
41       return D.Value;
42     if (D.Value == uintX_t(-1))
43       return Sec->Addr + Sec->Size;
44     return Sec->Addr + D.Value;
45   }
46   case SymbolBody::DefinedRegularKind: {
47     auto &D = cast<DefinedRegular<ELFT>>(Body);
48     InputSectionBase<ELFT> *IS = D.Section;
49
50     // According to the ELF spec reference to a local symbol from outside
51     // the group are not allowed. Unfortunately .eh_frame breaks that rule
52     // and must be treated specially. For now we just replace the symbol with
53     // 0.
54     if (IS == &InputSection<ELFT>::Discarded)
55       return 0;
56
57     // This is an absolute symbol.
58     if (!IS)
59       return D.Value;
60
61     uintX_t Offset = D.Value;
62     if (D.isSection()) {
63       Offset += Addend;
64       Addend = 0;
65     }
66     uintX_t VA = (IS->OutSec ? IS->OutSec->Addr : 0) + IS->getOffset(Offset);
67     if (D.isTls() && !Config->Relocatable) {
68       if (!Out<ELFT>::TlsPhdr)
69         fatal(toString(D.File) +
70               " has a STT_TLS symbol but doesn't have a PT_TLS section");
71       return VA - Out<ELFT>::TlsPhdr->p_vaddr;
72     }
73     return VA;
74   }
75   case SymbolBody::DefinedCommonKind:
76     return In<ELFT>::Common->OutSec->Addr + In<ELFT>::Common->OutSecOff +
77            cast<DefinedCommon>(Body).Offset;
78   case SymbolBody::SharedKind: {
79     auto &SS = cast<SharedSymbol<ELFT>>(Body);
80     if (!SS.NeedsCopyOrPltAddr)
81       return 0;
82     if (SS.isFunc())
83       return Body.getPltVA<ELFT>();
84     return Out<ELFT>::Bss->Addr + SS.OffsetInBss;
85   }
86   case SymbolBody::UndefinedKind:
87     return 0;
88   case SymbolBody::LazyArchiveKind:
89   case SymbolBody::LazyObjectKind:
90     assert(Body.symbol()->IsUsedInRegularObj && "lazy symbol reached writer");
91     return 0;
92   }
93   llvm_unreachable("invalid symbol kind");
94 }
95
96 SymbolBody::SymbolBody(Kind K, StringRefZ Name, bool IsLocal, uint8_t StOther,
97                        uint8_t Type)
98     : SymbolKind(K), NeedsCopyOrPltAddr(false), IsLocal(IsLocal),
99       IsInGlobalMipsGot(false), Is32BitMipsGot(false), IsInIplt(false),
100       IsInIgot(false), Type(Type), StOther(StOther), Name(Name) {}
101
102 // Returns true if a symbol can be replaced at load-time by a symbol
103 // with the same name defined in other ELF executable or DSO.
104 bool SymbolBody::isPreemptible() const {
105   if (isLocal())
106     return false;
107
108   // Shared symbols resolve to the definition in the DSO. The exceptions are
109   // symbols with copy relocations (which resolve to .bss) or preempt plt
110   // entries (which resolve to that plt entry).
111   if (isShared())
112     return !NeedsCopyOrPltAddr;
113
114   // That's all that can be preempted in a non-DSO.
115   if (!Config->Shared)
116     return false;
117
118   // Only symbols that appear in dynsym can be preempted.
119   if (!symbol()->includeInDynsym())
120     return false;
121
122   // Only default visibility symbols can be preempted.
123   if (symbol()->Visibility != STV_DEFAULT)
124     return false;
125
126   // -Bsymbolic means that definitions are not preempted.
127   if (Config->Bsymbolic || (Config->BsymbolicFunctions && isFunc()))
128     return !isDefined();
129   return true;
130 }
131
132 template <class ELFT> bool SymbolBody::hasThunk() const {
133   if (auto *DR = dyn_cast<DefinedRegular<ELFT>>(this))
134     return DR->ThunkData != nullptr;
135   if (auto *S = dyn_cast<SharedSymbol<ELFT>>(this))
136     return S->ThunkData != nullptr;
137   return false;
138 }
139
140 template <class ELFT>
141 typename ELFT::uint SymbolBody::getVA(typename ELFT::uint Addend) const {
142   typename ELFT::uint OutVA = getSymVA<ELFT>(*this, Addend);
143   return OutVA + Addend;
144 }
145
146 template <class ELFT> typename ELFT::uint SymbolBody::getGotVA() const {
147   return In<ELFT>::Got->getVA() + getGotOffset<ELFT>();
148 }
149
150 template <class ELFT> typename ELFT::uint SymbolBody::getGotOffset() const {
151   return GotIndex * Target->GotEntrySize;
152 }
153
154 template <class ELFT> typename ELFT::uint SymbolBody::getGotPltVA() const {
155   if (this->IsInIgot)
156     return In<ELFT>::IgotPlt->getVA() + getGotPltOffset<ELFT>();
157   return In<ELFT>::GotPlt->getVA() + getGotPltOffset<ELFT>();
158 }
159
160 template <class ELFT> typename ELFT::uint SymbolBody::getGotPltOffset() const {
161   return GotPltIndex * Target->GotPltEntrySize;
162 }
163
164 template <class ELFT> typename ELFT::uint SymbolBody::getPltVA() const {
165   if (this->IsInIplt)
166     return In<ELFT>::Iplt->getVA() + PltIndex * Target->PltEntrySize;
167   return In<ELFT>::Plt->getVA() + Target->PltHeaderSize +
168          PltIndex * Target->PltEntrySize;
169 }
170
171 template <class ELFT> typename ELFT::uint SymbolBody::getThunkVA() const {
172   if (const auto *DR = dyn_cast<DefinedRegular<ELFT>>(this))
173     return DR->ThunkData->getVA();
174   if (const auto *S = dyn_cast<SharedSymbol<ELFT>>(this))
175     return S->ThunkData->getVA();
176   if (const auto *S = dyn_cast<Undefined<ELFT>>(this))
177     return S->ThunkData->getVA();
178   fatal("getThunkVA() not supported for Symbol class\n");
179 }
180
181 template <class ELFT> typename ELFT::uint SymbolBody::getSize() const {
182   if (const auto *C = dyn_cast<DefinedCommon>(this))
183     return C->Size;
184   if (const auto *DR = dyn_cast<DefinedRegular<ELFT>>(this))
185     return DR->Size;
186   if (const auto *S = dyn_cast<SharedSymbol<ELFT>>(this))
187     return S->Sym.st_size;
188   return 0;
189 }
190
191 // If a symbol name contains '@', the characters after that is
192 // a symbol version name. This function parses that.
193 void SymbolBody::parseSymbolVersion() {
194   StringRef S = getName();
195   size_t Pos = S.find('@');
196   if (Pos == 0 || Pos == StringRef::npos)
197     return;
198   StringRef Verstr = S.substr(Pos + 1);
199   if (Verstr.empty())
200     return;
201
202   // Truncate the symbol name so that it doesn't include the version string.
203   Name = {S.data(), Pos};
204
205   // '@@' in a symbol name means the default version.
206   // It is usually the most recent one.
207   bool IsDefault = (Verstr[0] == '@');
208   if (IsDefault)
209     Verstr = Verstr.substr(1);
210
211   for (VersionDefinition &Ver : Config->VersionDefinitions) {
212     if (Ver.Name != Verstr)
213       continue;
214
215     if (IsDefault)
216       symbol()->VersionId = Ver.Id;
217     else
218       symbol()->VersionId = Ver.Id | VERSYM_HIDDEN;
219     return;
220   }
221
222   // It is an error if the specified version is not defined.
223   error(toString(File) + ": symbol " + S + " has undefined version " + Verstr);
224 }
225
226 Defined::Defined(Kind K, StringRefZ Name, bool IsLocal, uint8_t StOther,
227                  uint8_t Type)
228     : SymbolBody(K, Name, IsLocal, StOther, Type) {}
229
230 template <class ELFT> bool DefinedRegular<ELFT>::isMipsPIC() const {
231   if (!Section || !isFunc())
232     return false;
233   return (this->StOther & STO_MIPS_MIPS16) == STO_MIPS_PIC ||
234          (Section->getFile()->getObj().getHeader()->e_flags & EF_MIPS_PIC);
235 }
236
237 template <typename ELFT>
238 Undefined<ELFT>::Undefined(StringRefZ Name, bool IsLocal, uint8_t StOther,
239                            uint8_t Type, InputFile *File)
240     : SymbolBody(SymbolBody::UndefinedKind, Name, IsLocal, StOther, Type) {
241   this->File = File;
242 }
243
244 DefinedCommon::DefinedCommon(StringRef Name, uint64_t Size, uint64_t Alignment,
245                              uint8_t StOther, uint8_t Type, InputFile *File)
246     : Defined(SymbolBody::DefinedCommonKind, Name, /*IsLocal=*/false, StOther,
247               Type),
248       Alignment(Alignment), Size(Size) {
249   this->File = File;
250 }
251
252 InputFile *Lazy::fetch() {
253   if (auto *S = dyn_cast<LazyArchive>(this))
254     return S->fetch();
255   return cast<LazyObject>(this)->fetch();
256 }
257
258 LazyArchive::LazyArchive(ArchiveFile &File,
259                          const llvm::object::Archive::Symbol S, uint8_t Type)
260     : Lazy(LazyArchiveKind, S.getName(), Type), Sym(S) {
261   this->File = &File;
262 }
263
264 LazyObject::LazyObject(StringRef Name, LazyObjectFile &File, uint8_t Type)
265     : Lazy(LazyObjectKind, Name, Type) {
266   this->File = &File;
267 }
268
269 InputFile *LazyArchive::fetch() {
270   std::pair<MemoryBufferRef, uint64_t> MBInfo = file()->getMember(&Sym);
271
272   // getMember returns an empty buffer if the member was already
273   // read from the library.
274   if (MBInfo.first.getBuffer().empty())
275     return nullptr;
276   return createObjectFile(MBInfo.first, file()->getName(), MBInfo.second);
277 }
278
279 InputFile *LazyObject::fetch() {
280   MemoryBufferRef MBRef = file()->getBuffer();
281   if (MBRef.getBuffer().empty())
282     return nullptr;
283   return createObjectFile(MBRef);
284 }
285
286 bool Symbol::includeInDynsym() const {
287   if (Visibility != STV_DEFAULT && Visibility != STV_PROTECTED)
288     return false;
289   return (ExportDynamic && VersionId != VER_NDX_LOCAL) || body()->isShared() ||
290          (body()->isUndefined() && Config->Shared);
291 }
292
293 // Print out a log message for --trace-symbol.
294 void elf::printTraceSymbol(Symbol *Sym) {
295   SymbolBody *B = Sym->body();
296   outs() << toString(B->File);
297
298   if (B->isUndefined())
299     outs() << ": reference to ";
300   else if (B->isCommon())
301     outs() << ": common definition of ";
302   else
303     outs() << ": definition of ";
304   outs() << B->getName() << "\n";
305 }
306
307 // Returns a symbol for an error message.
308 std::string elf::toString(const SymbolBody &B) {
309   if (Config->Demangle)
310     if (Optional<std::string> S = demangle(B.getName()))
311       return *S;
312   return B.getName();
313 }
314
315 template bool SymbolBody::hasThunk<ELF32LE>() const;
316 template bool SymbolBody::hasThunk<ELF32BE>() const;
317 template bool SymbolBody::hasThunk<ELF64LE>() const;
318 template bool SymbolBody::hasThunk<ELF64BE>() const;
319
320 template uint32_t SymbolBody::template getVA<ELF32LE>(uint32_t) const;
321 template uint32_t SymbolBody::template getVA<ELF32BE>(uint32_t) const;
322 template uint64_t SymbolBody::template getVA<ELF64LE>(uint64_t) const;
323 template uint64_t SymbolBody::template getVA<ELF64BE>(uint64_t) const;
324
325 template uint32_t SymbolBody::template getGotVA<ELF32LE>() const;
326 template uint32_t SymbolBody::template getGotVA<ELF32BE>() const;
327 template uint64_t SymbolBody::template getGotVA<ELF64LE>() const;
328 template uint64_t SymbolBody::template getGotVA<ELF64BE>() const;
329
330 template uint32_t SymbolBody::template getGotOffset<ELF32LE>() const;
331 template uint32_t SymbolBody::template getGotOffset<ELF32BE>() const;
332 template uint64_t SymbolBody::template getGotOffset<ELF64LE>() const;
333 template uint64_t SymbolBody::template getGotOffset<ELF64BE>() const;
334
335 template uint32_t SymbolBody::template getGotPltVA<ELF32LE>() const;
336 template uint32_t SymbolBody::template getGotPltVA<ELF32BE>() const;
337 template uint64_t SymbolBody::template getGotPltVA<ELF64LE>() const;
338 template uint64_t SymbolBody::template getGotPltVA<ELF64BE>() const;
339
340 template uint32_t SymbolBody::template getThunkVA<ELF32LE>() const;
341 template uint32_t SymbolBody::template getThunkVA<ELF32BE>() const;
342 template uint64_t SymbolBody::template getThunkVA<ELF64LE>() const;
343 template uint64_t SymbolBody::template getThunkVA<ELF64BE>() const;
344
345 template uint32_t SymbolBody::template getGotPltOffset<ELF32LE>() const;
346 template uint32_t SymbolBody::template getGotPltOffset<ELF32BE>() const;
347 template uint64_t SymbolBody::template getGotPltOffset<ELF64LE>() const;
348 template uint64_t SymbolBody::template getGotPltOffset<ELF64BE>() const;
349
350 template uint32_t SymbolBody::template getPltVA<ELF32LE>() const;
351 template uint32_t SymbolBody::template getPltVA<ELF32BE>() const;
352 template uint64_t SymbolBody::template getPltVA<ELF64LE>() const;
353 template uint64_t SymbolBody::template getPltVA<ELF64BE>() const;
354
355 template uint32_t SymbolBody::template getSize<ELF32LE>() const;
356 template uint32_t SymbolBody::template getSize<ELF32BE>() const;
357 template uint64_t SymbolBody::template getSize<ELF64LE>() const;
358 template uint64_t SymbolBody::template getSize<ELF64BE>() const;
359
360 template class elf::Undefined<ELF32LE>;
361 template class elf::Undefined<ELF32BE>;
362 template class elf::Undefined<ELF64LE>;
363 template class elf::Undefined<ELF64BE>;
364
365 template class elf::DefinedRegular<ELF32LE>;
366 template class elf::DefinedRegular<ELF32BE>;
367 template class elf::DefinedRegular<ELF64LE>;
368 template class elf::DefinedRegular<ELF64BE>;