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