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