xref: /llvm-project-15.0.7/lld/ELF/Symbols.cpp (revision fdcca8cd)
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 #include "llvm/Config/config.h"
19 
20 #ifdef HAVE_CXXABI_H
21 #include <cxxabi.h>
22 #endif
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<ELFT>>(Body);
39     const OutputSectionBase<ELFT> *Sec = D.Section;
40     if (!Sec)
41       return D.Value;
42     if (D.Value == DefinedSynthetic<ELFT>::SectionEnd)
43       return Sec->getVA() + Sec->getSize();
44     return Sec->getVA() + D.Value;
45   }
46   case SymbolBody::DefinedRegularKind: {
47     auto &D = cast<DefinedRegular<ELFT>>(Body);
48     InputSectionBase<ELFT> *SC = 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 (SC == &InputSection<ELFT>::Discarded)
55       return 0;
56 
57     // This is an absolute symbol.
58     if (!SC)
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 = SC->OutSec->getVA() + SC->getOffset(Offset);
67     if (D.isTls())
68       return VA - Out<ELFT>::TlsPhdr->p_vaddr;
69     return VA;
70   }
71   case SymbolBody::DefinedCommonKind:
72     return Out<ELFT>::Bss->getVA() + cast<DefinedCommon>(Body).OffsetInBss;
73   case SymbolBody::SharedKind: {
74     auto &SS = cast<SharedSymbol<ELFT>>(Body);
75     if (!SS.NeedsCopyOrPltAddr)
76       return 0;
77     if (SS.isFunc())
78       return Body.getPltVA<ELFT>();
79     return Out<ELFT>::Bss->getVA() + SS.OffsetInBss;
80   }
81   case SymbolBody::UndefinedKind:
82     return 0;
83   case SymbolBody::LazyArchiveKind:
84   case SymbolBody::LazyObjectKind:
85     assert(Body.symbol()->IsUsedInRegularObj && "lazy symbol reached writer");
86     return 0;
87   case SymbolBody::DefinedBitcodeKind:
88     llvm_unreachable("should have been replaced");
89   }
90   llvm_unreachable("invalid symbol kind");
91 }
92 
93 SymbolBody::SymbolBody(Kind K, uint32_t NameOffset, uint8_t StOther,
94                        uint8_t Type)
95     : SymbolKind(K), NeedsCopyOrPltAddr(false), IsLocal(true),
96       IsInGlobalMipsGot(false), Type(Type), StOther(StOther),
97       NameOffset(NameOffset) {}
98 
99 SymbolBody::SymbolBody(Kind K, StringRef Name, uint8_t StOther, uint8_t Type)
100     : SymbolKind(K), NeedsCopyOrPltAddr(false), IsLocal(false),
101       IsInGlobalMipsGot(false), Type(Type), StOther(StOther),
102       Name({Name.data(), Name.size()}) {}
103 
104 StringRef SymbolBody::getName() const {
105   assert(!isLocal());
106   StringRef S = StringRef(Name.S, Name.Len);
107   if (!symbol()->VersionedName)
108     return S;
109   return S.substr(0, S.find('@'));
110 }
111 
112 // Returns true if a symbol can be replaced at load-time by a symbol
113 // with the same name defined in other ELF executable or DSO.
114 bool SymbolBody::isPreemptible() const {
115   if (isLocal())
116     return false;
117 
118   // Shared symbols resolve to the definition in the DSO. The exceptions are
119   // symbols with copy relocations (which resolve to .bss) or preempt plt
120   // entries (which resolve to that plt entry).
121   if (isShared())
122     return !NeedsCopyOrPltAddr;
123 
124   // That's all that can be preempted in a non-DSO.
125   if (!Config->Shared)
126     return false;
127 
128   // Only symbols that appear in dynsym can be preempted.
129   if (!symbol()->includeInDynsym())
130     return false;
131 
132   // Normally only default visibility symbols can be preempted, but -Bsymbolic
133   // means that not even they can be preempted.
134   if (Config->Bsymbolic || (Config->BsymbolicFunctions && isFunc()))
135     return !isDefined();
136   return symbol()->Visibility == STV_DEFAULT;
137 }
138 
139 template <class ELFT> InputFile *SymbolBody::getSourceFile() {
140   if (auto *S = dyn_cast<DefinedRegular<ELFT>>(this))
141     return S->Section ? S->Section->getFile() : nullptr;
142   if (auto *S = dyn_cast<SharedSymbol<ELFT>>(this))
143     return S->File;
144   if (auto *S = dyn_cast<DefinedBitcode>(this))
145     return S->File;
146   if (auto *S = dyn_cast<Undefined>(this))
147     return S->File;
148   return nullptr;
149 }
150 
151 template <class ELFT>
152 typename ELFT::uint SymbolBody::getVA(typename ELFT::uint Addend) const {
153   typename ELFT::uint OutVA = getSymVA<ELFT>(*this, Addend);
154   return OutVA + Addend;
155 }
156 
157 template <class ELFT> typename ELFT::uint SymbolBody::getGotVA() const {
158   return Out<ELFT>::Got->getVA() + getGotOffset<ELFT>();
159 }
160 
161 template <class ELFT> typename ELFT::uint SymbolBody::getGotOffset() const {
162   return GotIndex * sizeof(typename ELFT::uint);
163 }
164 
165 template <class ELFT> typename ELFT::uint SymbolBody::getGotPltVA() const {
166   return Out<ELFT>::GotPlt->getVA() + getGotPltOffset<ELFT>();
167 }
168 
169 template <class ELFT> typename ELFT::uint SymbolBody::getGotPltOffset() const {
170   return GotPltIndex * sizeof(typename ELFT::uint);
171 }
172 
173 template <class ELFT> typename ELFT::uint SymbolBody::getPltVA() const {
174   return Out<ELFT>::Plt->getVA() + Target->PltHeaderSize +
175          PltIndex * Target->PltEntrySize;
176 }
177 
178 template <class ELFT> typename ELFT::uint SymbolBody::getThunkVA() const {
179   auto *D = cast<DefinedRegular<ELFT>>(this);
180   auto *S = cast<InputSection<ELFT>>(D->Section);
181   return S->OutSec->getVA() + S->OutSecOff + S->getThunkOff() +
182          ThunkIndex * Target->ThunkSize;
183 }
184 
185 template <class ELFT> typename ELFT::uint SymbolBody::getSize() const {
186   if (const auto *C = dyn_cast<DefinedCommon>(this))
187     return C->Size;
188   if (const auto *DR = dyn_cast<DefinedRegular<ELFT>>(this))
189     return DR->Size;
190   if (const auto *S = dyn_cast<SharedSymbol<ELFT>>(this))
191     return S->Sym.st_size;
192   return 0;
193 }
194 
195 Defined::Defined(Kind K, StringRef Name, uint8_t StOther, uint8_t Type)
196     : SymbolBody(K, Name, StOther, Type) {}
197 
198 Defined::Defined(Kind K, uint32_t NameOffset, uint8_t StOther, uint8_t Type)
199     : SymbolBody(K, NameOffset, StOther, Type) {}
200 
201 DefinedBitcode::DefinedBitcode(StringRef Name, uint8_t StOther, uint8_t Type,
202                                BitcodeFile *F)
203     : Defined(DefinedBitcodeKind, Name, StOther, Type), File(F) {}
204 
205 bool DefinedBitcode::classof(const SymbolBody *S) {
206   return S->kind() == DefinedBitcodeKind;
207 }
208 
209 Undefined::Undefined(StringRef Name, uint8_t StOther, uint8_t Type)
210     : SymbolBody(SymbolBody::UndefinedKind, Name, StOther, Type) {}
211 
212 Undefined::Undefined(uint32_t NameOffset, uint8_t StOther, uint8_t Type)
213     : SymbolBody(SymbolBody::UndefinedKind, NameOffset, StOther, Type) {}
214 
215 template <typename ELFT>
216 DefinedSynthetic<ELFT>::DefinedSynthetic(StringRef N, uintX_t Value,
217                                          OutputSectionBase<ELFT> *Section)
218     : Defined(SymbolBody::DefinedSyntheticKind, N, STV_HIDDEN, 0 /* Type */),
219       Value(Value), Section(Section) {}
220 
221 DefinedCommon::DefinedCommon(StringRef N, uint64_t Size, uint64_t Alignment,
222                              uint8_t StOther, uint8_t Type)
223     : Defined(SymbolBody::DefinedCommonKind, N, StOther, Type),
224       Alignment(Alignment), Size(Size) {}
225 
226 std::unique_ptr<InputFile> Lazy::getFile() {
227   if (auto *S = dyn_cast<LazyArchive>(this))
228     return S->getFile();
229   return cast<LazyObject>(this)->getFile();
230 }
231 
232 std::unique_ptr<InputFile> LazyArchive::getFile() {
233   MemoryBufferRef MBRef = File.getMember(&Sym);
234 
235   // getMember returns an empty buffer if the member was already
236   // read from the library.
237   if (MBRef.getBuffer().empty())
238     return std::unique_ptr<InputFile>(nullptr);
239   return createObjectFile(MBRef, File.getName());
240 }
241 
242 std::unique_ptr<InputFile> LazyObject::getFile() {
243   MemoryBufferRef MBRef = File.getBuffer();
244   if (MBRef.getBuffer().empty())
245     return std::unique_ptr<InputFile>(nullptr);
246   return createObjectFile(MBRef);
247 }
248 
249 // Returns the demangled C++ symbol name for Name.
250 std::string elf::demangle(StringRef Name) {
251 #if !defined(HAVE_CXXABI_H)
252   return Name;
253 #else
254   if (!Config->Demangle)
255     return Name;
256 
257   // __cxa_demangle can be used to demangle strings other than symbol
258   // names which do not necessarily start with "_Z". Name can be
259   // either a C or C++ symbol. Don't call __cxa_demangle if the name
260   // does not look like a C++ symbol name to avoid getting unexpected
261   // result for a C symbol that happens to match a mangled type name.
262   if (!Name.startswith("_Z"))
263     return Name;
264 
265   char *Buf =
266       abi::__cxa_demangle(Name.str().c_str(), nullptr, nullptr, nullptr);
267   if (!Buf)
268     return Name;
269   std::string S(Buf);
270   free(Buf);
271   return S;
272 #endif
273 }
274 
275 bool Symbol::includeInDynsym() const {
276   if (Visibility != STV_DEFAULT && Visibility != STV_PROTECTED)
277     return false;
278   return (ExportDynamic && VersionId != VER_NDX_LOCAL) || body()->isShared() ||
279          (body()->isUndefined() && Config->Shared);
280 }
281 
282 template InputFile *SymbolBody::template getSourceFile<ELF32LE>();
283 template InputFile *SymbolBody::template getSourceFile<ELF32BE>();
284 template InputFile *SymbolBody::template getSourceFile<ELF64LE>();
285 template InputFile *SymbolBody::template getSourceFile<ELF64BE>();
286 
287 template uint32_t SymbolBody::template getVA<ELF32LE>(uint32_t) const;
288 template uint32_t SymbolBody::template getVA<ELF32BE>(uint32_t) const;
289 template uint64_t SymbolBody::template getVA<ELF64LE>(uint64_t) const;
290 template uint64_t SymbolBody::template getVA<ELF64BE>(uint64_t) const;
291 
292 template uint32_t SymbolBody::template getGotVA<ELF32LE>() const;
293 template uint32_t SymbolBody::template getGotVA<ELF32BE>() const;
294 template uint64_t SymbolBody::template getGotVA<ELF64LE>() const;
295 template uint64_t SymbolBody::template getGotVA<ELF64BE>() const;
296 
297 template uint32_t SymbolBody::template getGotOffset<ELF32LE>() const;
298 template uint32_t SymbolBody::template getGotOffset<ELF32BE>() const;
299 template uint64_t SymbolBody::template getGotOffset<ELF64LE>() const;
300 template uint64_t SymbolBody::template getGotOffset<ELF64BE>() const;
301 
302 template uint32_t SymbolBody::template getGotPltVA<ELF32LE>() const;
303 template uint32_t SymbolBody::template getGotPltVA<ELF32BE>() const;
304 template uint64_t SymbolBody::template getGotPltVA<ELF64LE>() const;
305 template uint64_t SymbolBody::template getGotPltVA<ELF64BE>() const;
306 
307 template uint32_t SymbolBody::template getGotPltOffset<ELF32LE>() const;
308 template uint32_t SymbolBody::template getGotPltOffset<ELF32BE>() const;
309 template uint64_t SymbolBody::template getGotPltOffset<ELF64LE>() const;
310 template uint64_t SymbolBody::template getGotPltOffset<ELF64BE>() const;
311 
312 template uint32_t SymbolBody::template getPltVA<ELF32LE>() const;
313 template uint32_t SymbolBody::template getPltVA<ELF32BE>() const;
314 template uint64_t SymbolBody::template getPltVA<ELF64LE>() const;
315 template uint64_t SymbolBody::template getPltVA<ELF64BE>() const;
316 
317 template uint32_t SymbolBody::template getSize<ELF32LE>() const;
318 template uint32_t SymbolBody::template getSize<ELF32BE>() const;
319 template uint64_t SymbolBody::template getSize<ELF64LE>() const;
320 template uint64_t SymbolBody::template getSize<ELF64BE>() const;
321 
322 template uint32_t SymbolBody::template getThunkVA<ELF32LE>() const;
323 template uint32_t SymbolBody::template getThunkVA<ELF32BE>() const;
324 template uint64_t SymbolBody::template getThunkVA<ELF64LE>() const;
325 template uint64_t SymbolBody::template getThunkVA<ELF64BE>() const;
326 
327 template class elf::DefinedSynthetic<ELF32LE>;
328 template class elf::DefinedSynthetic<ELF32BE>;
329 template class elf::DefinedSynthetic<ELF64LE>;
330 template class elf::DefinedSynthetic<ELF64BE>;
331