xref: /llvm-project-15.0.7/lld/ELF/Symbols.cpp (revision 4de8e6d2)
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), Type(Type),
96       StOther(StOther), NameOffset(NameOffset) {}
97 
98 SymbolBody::SymbolBody(Kind K, StringRef Name, uint8_t StOther, uint8_t Type)
99     : SymbolKind(K), NeedsCopyOrPltAddr(false), IsLocal(false), Type(Type),
100       StOther(StOther), Name({Name.data(), Name.size()}) {}
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   // Normally only default visibility symbols can be preempted, but -Bsymbolic
123   // means that not even they can be preempted.
124   if (Config->Bsymbolic || (Config->BsymbolicFunctions && isFunc()))
125     return !isDefined();
126   return symbol()->Visibility == STV_DEFAULT;
127 }
128 
129 template <class ELFT> InputFile *SymbolBody::getSourceFile() {
130   if (auto *S = dyn_cast<DefinedRegular<ELFT>>(this))
131     return S->Section ? S->Section->getFile() : nullptr;
132   if (auto *S = dyn_cast<SharedSymbol<ELFT>>(this))
133     return S->File;
134   if (auto *S = dyn_cast<DefinedBitcode>(this))
135     return S->File;
136   if (auto *S = dyn_cast<Undefined>(this))
137     return S->File;
138   return nullptr;
139 }
140 
141 template <class ELFT>
142 typename ELFT::uint SymbolBody::getVA(typename ELFT::uint Addend) const {
143   typename ELFT::uint OutVA = getSymVA<ELFT>(*this, Addend);
144   return OutVA + Addend;
145 }
146 
147 template <class ELFT> typename ELFT::uint SymbolBody::getGotVA() const {
148   return Out<ELFT>::Got->getVA() + getGotOffset<ELFT>();
149 }
150 
151 template <class ELFT> typename ELFT::uint SymbolBody::getGotOffset() const {
152   return (Out<ELFT>::Got->getMipsLocalEntriesNum() + GotIndex) *
153          sizeof(typename ELFT::uint);
154 }
155 
156 template <class ELFT> typename ELFT::uint SymbolBody::getGotPltVA() const {
157   return Out<ELFT>::GotPlt->getVA() + getGotPltOffset<ELFT>();
158 }
159 
160 template <class ELFT> typename ELFT::uint SymbolBody::getGotPltOffset() const {
161   return GotPltIndex * sizeof(typename ELFT::uint);
162 }
163 
164 template <class ELFT> typename ELFT::uint SymbolBody::getPltVA() const {
165   return Out<ELFT>::Plt->getVA() + Target->PltZeroSize +
166          PltIndex * Target->PltEntrySize;
167 }
168 
169 template <class ELFT> typename ELFT::uint SymbolBody::getThunkVA() const {
170   auto *D = cast<DefinedRegular<ELFT>>(this);
171   auto *S = cast<InputSection<ELFT>>(D->Section);
172   return S->OutSec->getVA() + S->OutSecOff + S->getThunkOff() +
173          ThunkIndex * Target->ThunkSize;
174 }
175 
176 template <class ELFT> typename ELFT::uint SymbolBody::getSize() const {
177   if (const auto *C = dyn_cast<DefinedCommon>(this))
178     return C->Size;
179   if (const auto *DR = dyn_cast<DefinedRegular<ELFT>>(this))
180     return DR->Size;
181   if (const auto *S = dyn_cast<SharedSymbol<ELFT>>(this))
182     return S->Sym.st_size;
183   return 0;
184 }
185 
186 Defined::Defined(Kind K, StringRef Name, uint8_t StOther, uint8_t Type)
187     : SymbolBody(K, Name, StOther, Type) {}
188 
189 Defined::Defined(Kind K, uint32_t NameOffset, uint8_t StOther, uint8_t Type)
190     : SymbolBody(K, NameOffset, StOther, Type) {}
191 
192 DefinedBitcode::DefinedBitcode(StringRef Name, uint8_t StOther, uint8_t Type,
193                                BitcodeFile *F)
194     : Defined(DefinedBitcodeKind, Name, StOther, Type), File(F) {}
195 
196 bool DefinedBitcode::classof(const SymbolBody *S) {
197   return S->kind() == DefinedBitcodeKind;
198 }
199 
200 Undefined::Undefined(StringRef Name, uint8_t StOther, uint8_t Type)
201     : SymbolBody(SymbolBody::UndefinedKind, Name, StOther, Type) {}
202 
203 Undefined::Undefined(uint32_t NameOffset, uint8_t StOther, uint8_t Type)
204     : SymbolBody(SymbolBody::UndefinedKind, NameOffset, StOther, Type) {}
205 
206 template <typename ELFT>
207 DefinedSynthetic<ELFT>::DefinedSynthetic(StringRef N, uintX_t Value,
208                                          OutputSectionBase<ELFT> *Section)
209     : Defined(SymbolBody::DefinedSyntheticKind, N, STV_HIDDEN, 0 /* Type */),
210       Value(Value), Section(Section) {}
211 
212 DefinedCommon::DefinedCommon(StringRef N, uint64_t Size, uint64_t Alignment,
213                              uint8_t StOther, uint8_t Type)
214     : Defined(SymbolBody::DefinedCommonKind, N, StOther, Type),
215       Alignment(Alignment), Size(Size) {}
216 
217 std::unique_ptr<InputFile> Lazy::getFile() {
218   if (auto *S = dyn_cast<LazyArchive>(this))
219     return S->getFile();
220   return cast<LazyObject>(this)->getFile();
221 }
222 
223 std::unique_ptr<InputFile> LazyArchive::getFile() {
224   MemoryBufferRef MBRef = File->getMember(&Sym);
225 
226   // getMember returns an empty buffer if the member was already
227   // read from the library.
228   if (MBRef.getBuffer().empty())
229     return std::unique_ptr<InputFile>(nullptr);
230   return createObjectFile(MBRef, File->getName());
231 }
232 
233 std::unique_ptr<InputFile> LazyObject::getFile() {
234   return createObjectFile(MBRef);
235 }
236 
237 // Returns the demangled C++ symbol name for Name.
238 std::string elf::demangle(StringRef Name) {
239 #if !defined(HAVE_CXXABI_H)
240   return Name;
241 #else
242   if (!Config->Demangle)
243     return Name;
244 
245   // __cxa_demangle can be used to demangle strings other than symbol
246   // names which do not necessarily start with "_Z". Name can be
247   // either a C or C++ symbol. Don't call __cxa_demangle if the name
248   // does not look like a C++ symbol name to avoid getting unexpected
249   // result for a C symbol that happens to match a mangled type name.
250   if (!Name.startswith("_Z"))
251     return Name;
252 
253   char *Buf =
254       abi::__cxa_demangle(Name.str().c_str(), nullptr, nullptr, nullptr);
255   if (!Buf)
256     return Name;
257   std::string S(Buf);
258   free(Buf);
259   return S;
260 #endif
261 }
262 
263 bool Symbol::includeInDynsym() const {
264   if (Visibility != STV_DEFAULT && Visibility != STV_PROTECTED)
265     return false;
266   return (ExportDynamic && VersionScriptGlobal) || body()->isShared() ||
267          (body()->isUndefined() && Config->Shared);
268 }
269 
270 template InputFile *SymbolBody::template getSourceFile<ELF32LE>();
271 template InputFile *SymbolBody::template getSourceFile<ELF32BE>();
272 template InputFile *SymbolBody::template getSourceFile<ELF64LE>();
273 template InputFile *SymbolBody::template getSourceFile<ELF64BE>();
274 
275 template uint32_t SymbolBody::template getVA<ELF32LE>(uint32_t) const;
276 template uint32_t SymbolBody::template getVA<ELF32BE>(uint32_t) const;
277 template uint64_t SymbolBody::template getVA<ELF64LE>(uint64_t) const;
278 template uint64_t SymbolBody::template getVA<ELF64BE>(uint64_t) const;
279 
280 template uint32_t SymbolBody::template getGotVA<ELF32LE>() const;
281 template uint32_t SymbolBody::template getGotVA<ELF32BE>() const;
282 template uint64_t SymbolBody::template getGotVA<ELF64LE>() const;
283 template uint64_t SymbolBody::template getGotVA<ELF64BE>() const;
284 
285 template uint32_t SymbolBody::template getGotOffset<ELF32LE>() const;
286 template uint32_t SymbolBody::template getGotOffset<ELF32BE>() const;
287 template uint64_t SymbolBody::template getGotOffset<ELF64LE>() const;
288 template uint64_t SymbolBody::template getGotOffset<ELF64BE>() const;
289 
290 template uint32_t SymbolBody::template getGotPltVA<ELF32LE>() const;
291 template uint32_t SymbolBody::template getGotPltVA<ELF32BE>() const;
292 template uint64_t SymbolBody::template getGotPltVA<ELF64LE>() const;
293 template uint64_t SymbolBody::template getGotPltVA<ELF64BE>() const;
294 
295 template uint32_t SymbolBody::template getGotPltOffset<ELF32LE>() const;
296 template uint32_t SymbolBody::template getGotPltOffset<ELF32BE>() const;
297 template uint64_t SymbolBody::template getGotPltOffset<ELF64LE>() const;
298 template uint64_t SymbolBody::template getGotPltOffset<ELF64BE>() const;
299 
300 template uint32_t SymbolBody::template getPltVA<ELF32LE>() const;
301 template uint32_t SymbolBody::template getPltVA<ELF32BE>() const;
302 template uint64_t SymbolBody::template getPltVA<ELF64LE>() const;
303 template uint64_t SymbolBody::template getPltVA<ELF64BE>() const;
304 
305 template uint32_t SymbolBody::template getSize<ELF32LE>() const;
306 template uint32_t SymbolBody::template getSize<ELF32BE>() const;
307 template uint64_t SymbolBody::template getSize<ELF64LE>() const;
308 template uint64_t SymbolBody::template getSize<ELF64BE>() const;
309 
310 template uint32_t SymbolBody::template getThunkVA<ELF32LE>() const;
311 template uint32_t SymbolBody::template getThunkVA<ELF32BE>() const;
312 template uint64_t SymbolBody::template getThunkVA<ELF64LE>() const;
313 template uint64_t SymbolBody::template getThunkVA<ELF64BE>() const;
314 
315 template class elf::DefinedSynthetic<ELF32LE>;
316 template class elf::DefinedSynthetic<ELF32BE>;
317 template class elf::DefinedSynthetic<ELF64LE>;
318 template class elf::DefinedSynthetic<ELF64BE>;
319