xref: /llvm-project-15.0.7/lld/ELF/Symbols.cpp (revision 4d75e8d6)
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 typename ELFFile<ELFT>::uintX_t SymbolBody::getVA() const {
33   switch (kind()) {
34   case DefinedSyntheticKind: {
35     auto *D = cast<DefinedSynthetic<ELFT>>(this);
36     return D->Section.getVA() + D->Value;
37   }
38   case DefinedRegularKind: {
39     auto *D = cast<DefinedRegular<ELFT>>(this);
40     InputSectionBase<ELFT> *SC = D->Section;
41 
42     // This is an absolute symbol.
43     if (!SC)
44       return D->Sym.st_value;
45     assert(SC->Live);
46 
47     // Symbol offsets for AMDGPU are the offsets in bytes of the symbols
48     // from the beginning of the section. Note that this part of AMDGPU's
49     // ELF spec is odd and not in line with the standard ELF.
50     if (Config->EMachine == EM_AMDGPU)
51       return SC->getOffset(D->Sym);
52 
53     if (D->Sym.getType() == STT_TLS)
54       return SC->OutSec->getVA() + SC->getOffset(D->Sym) -
55              Out<ELFT>::TlsPhdr->p_vaddr;
56     return SC->OutSec->getVA() + SC->getOffset(D->Sym);
57   }
58   case DefinedCommonKind:
59     return Out<ELFT>::Bss->getVA() + cast<DefinedCommon>(this)->OffsetInBss;
60   case SharedKind: {
61     auto *SS = cast<SharedSymbol<ELFT>>(this);
62     if (!SS->NeedsCopyOrPltAddr)
63       return 0;
64     if (SS->IsFunc)
65       return getPltVA<ELFT>();
66     else
67       return Out<ELFT>::Bss->getVA() + SS->OffsetInBss;
68   }
69   case UndefinedElfKind:
70   case UndefinedKind:
71     return 0;
72   case LazyKind:
73     assert(isUsedInRegularObj() && "Lazy symbol reached writer");
74     return 0;
75   case DefinedBitcodeKind:
76     llvm_unreachable("Should have been replaced");
77   }
78   llvm_unreachable("Invalid symbol kind");
79 }
80 
81 template <class ELFT>
82 typename ELFFile<ELFT>::uintX_t SymbolBody::getGotVA() const {
83   return Out<ELFT>::Got->getVA() +
84          (Out<ELFT>::Got->getMipsLocalEntriesNum() + GotIndex) *
85              sizeof(typename ELFFile<ELFT>::uintX_t);
86 }
87 
88 template <class ELFT>
89 typename ELFFile<ELFT>::uintX_t SymbolBody::getGotPltVA() const {
90   return Out<ELFT>::GotPlt->getVA() +
91          GotPltIndex * sizeof(typename ELFFile<ELFT>::uintX_t);
92 }
93 
94 template <class ELFT>
95 typename ELFFile<ELFT>::uintX_t SymbolBody::getPltVA() const {
96   return Out<ELFT>::Plt->getVA() + Target->PltZeroSize +
97          PltIndex * Target->PltEntrySize;
98 }
99 
100 template <class ELFT>
101 typename ELFFile<ELFT>::uintX_t SymbolBody::getSize() const {
102   if (auto *B = dyn_cast<DefinedElf<ELFT>>(this))
103     return B->Sym.st_size;
104   return 0;
105 }
106 
107 static uint8_t getMinVisibility(uint8_t VA, uint8_t VB) {
108   if (VA == STV_DEFAULT)
109     return VB;
110   if (VB == STV_DEFAULT)
111     return VA;
112   return std::min(VA, VB);
113 }
114 
115 // Returns 1, 0 or -1 if this symbol should take precedence
116 // over the Other, tie or lose, respectively.
117 template <class ELFT> int SymbolBody::compare(SymbolBody *Other) {
118   typedef typename ELFFile<ELFT>::uintX_t uintX_t;
119   assert(!isLazy() && !Other->isLazy());
120   std::tuple<bool, bool, bool> L(isDefined(), !isShared(), !isWeak());
121   std::tuple<bool, bool, bool> R(Other->isDefined(), !Other->isShared(),
122                                  !Other->isWeak());
123 
124   // Normalize
125   if (L > R)
126     return -Other->compare<ELFT>(this);
127 
128   Visibility = Other->Visibility =
129       getMinVisibility(Visibility, Other->Visibility);
130 
131   if (IsUsedInRegularObj || Other->IsUsedInRegularObj)
132     IsUsedInRegularObj = Other->IsUsedInRegularObj = true;
133 
134   // We want to export all symbols that exist both in the executable
135   // and in DSOs, so that the symbols in the executable can interrupt
136   // symbols in the DSO at runtime.
137   if (isShared() != Other->isShared())
138     if (isa<DefinedRegular<ELFT>>(isShared() ? Other : this))
139       MustBeInDynSym = Other->MustBeInDynSym = true;
140 
141   if (L != R)
142     return -1;
143   if (!std::get<0>(L) || !std::get<1>(L) || !std::get<2>(L))
144     return 1;
145   if (isCommon()) {
146     if (!Other->isCommon())
147       return -1;
148     auto *ThisC = cast<DefinedCommon>(this);
149     auto *OtherC = cast<DefinedCommon>(Other);
150     uintX_t Align = std::max(ThisC->MaxAlignment, OtherC->MaxAlignment);
151     if (ThisC->Size >= OtherC->Size) {
152       ThisC->MaxAlignment = Align;
153       return 1;
154     }
155     OtherC->MaxAlignment = Align;
156     return -1;
157   }
158   if (Other->isCommon())
159     return 1;
160   return 0;
161 }
162 
163 Defined::Defined(Kind K, StringRef Name, bool IsWeak, uint8_t Visibility,
164                  bool IsTls, bool IsFunction)
165     : SymbolBody(K, Name, IsWeak, Visibility, IsTls, IsFunction) {}
166 
167 DefinedBitcode::DefinedBitcode(StringRef Name, bool IsWeak)
168     : Defined(DefinedBitcodeKind, Name, IsWeak, STV_DEFAULT, false, false) {}
169 
170 bool DefinedBitcode::classof(const SymbolBody *S) {
171   return S->kind() == DefinedBitcodeKind;
172 }
173 
174 Undefined::Undefined(SymbolBody::Kind K, StringRef N, bool IsWeak,
175                      uint8_t Visibility, bool IsTls)
176     : SymbolBody(K, N, IsWeak, Visibility, IsTls, /*IsFunction*/ false),
177       CanKeepUndefined(false) {}
178 
179 Undefined::Undefined(StringRef N, bool IsWeak, uint8_t Visibility,
180                      bool CanKeepUndefined)
181     : Undefined(SymbolBody::UndefinedKind, N, IsWeak, Visibility,
182                 /*IsTls*/ false) {
183   this->CanKeepUndefined = CanKeepUndefined;
184 }
185 
186 template <typename ELFT>
187 UndefinedElf<ELFT>::UndefinedElf(StringRef N, const Elf_Sym &Sym)
188     : Undefined(SymbolBody::UndefinedElfKind, N,
189                 Sym.getBinding() == llvm::ELF::STB_WEAK, Sym.getVisibility(),
190                 Sym.getType() == llvm::ELF::STT_TLS),
191       Sym(Sym) {}
192 
193 template <typename ELFT>
194 DefinedSynthetic<ELFT>::DefinedSynthetic(StringRef N, uintX_t Value,
195                                          OutputSectionBase<ELFT> &Section)
196     : Defined(SymbolBody::DefinedSyntheticKind, N, false, STV_DEFAULT,
197               /*IsTls*/ false, /*IsFunction*/ false),
198       Value(Value), Section(Section) {}
199 
200 DefinedCommon::DefinedCommon(StringRef N, uint64_t Size, uint64_t Alignment,
201                              bool IsWeak, uint8_t Visibility)
202     : Defined(SymbolBody::DefinedCommonKind, N, IsWeak, Visibility,
203               /*IsTls*/ false, /*IsFunction*/ false) {
204   MaxAlignment = Alignment;
205   this->Size = Size;
206 }
207 
208 std::unique_ptr<InputFile> Lazy::getMember() {
209   MemoryBufferRef MBRef = File->getMember(&Sym);
210 
211   // getMember returns an empty buffer if the member was already
212   // read from the library.
213   if (MBRef.getBuffer().empty())
214     return std::unique_ptr<InputFile>(nullptr);
215   return createObjectFile(MBRef, File->getName());
216 }
217 
218 template <class ELFT> static void doInitSymbols() {
219   ElfSym<ELFT>::Etext.setBinding(STB_GLOBAL);
220   ElfSym<ELFT>::Edata.setBinding(STB_GLOBAL);
221   ElfSym<ELFT>::End.setBinding(STB_GLOBAL);
222   ElfSym<ELFT>::Ignored.setBinding(STB_WEAK);
223   ElfSym<ELFT>::Ignored.setVisibility(STV_HIDDEN);
224 }
225 
226 void elf::initSymbols() {
227   doInitSymbols<ELF32LE>();
228   doInitSymbols<ELF32BE>();
229   doInitSymbols<ELF64LE>();
230   doInitSymbols<ELF64BE>();
231 }
232 
233 // Returns the demangled C++ symbol name for Name.
234 std::string elf::demangle(StringRef Name) {
235 #if !defined(HAVE_CXXABI_H)
236   return Name;
237 #else
238   if (!Config->Demangle)
239     return Name;
240 
241   // __cxa_demangle can be used to demangle strings other than symbol
242   // names which do not necessarily start with "_Z". Name can be
243   // either a C or C++ symbol. Don't call __cxa_demangle if the name
244   // does not look like a C++ symbol name to avoid getting unexpected
245   // result for a C symbol that happens to match a mangled type name.
246   if (!Name.startswith("_Z"))
247     return Name;
248 
249   char *Buf =
250       abi::__cxa_demangle(Name.str().c_str(), nullptr, nullptr, nullptr);
251   if (!Buf)
252     return Name;
253   std::string S(Buf);
254   free(Buf);
255   return S;
256 #endif
257 }
258 
259 template uint32_t SymbolBody::template getVA<ELF32LE>() const;
260 template uint32_t SymbolBody::template getVA<ELF32BE>() const;
261 template uint64_t SymbolBody::template getVA<ELF64LE>() const;
262 template uint64_t SymbolBody::template getVA<ELF64BE>() const;
263 
264 template uint32_t SymbolBody::template getGotVA<ELF32LE>() const;
265 template uint32_t SymbolBody::template getGotVA<ELF32BE>() const;
266 template uint64_t SymbolBody::template getGotVA<ELF64LE>() const;
267 template uint64_t SymbolBody::template getGotVA<ELF64BE>() const;
268 
269 template uint32_t SymbolBody::template getGotPltVA<ELF32LE>() const;
270 template uint32_t SymbolBody::template getGotPltVA<ELF32BE>() const;
271 template uint64_t SymbolBody::template getGotPltVA<ELF64LE>() const;
272 template uint64_t SymbolBody::template getGotPltVA<ELF64BE>() const;
273 
274 template uint32_t SymbolBody::template getPltVA<ELF32LE>() const;
275 template uint32_t SymbolBody::template getPltVA<ELF32BE>() const;
276 template uint64_t SymbolBody::template getPltVA<ELF64LE>() const;
277 template uint64_t SymbolBody::template getPltVA<ELF64BE>() const;
278 
279 template uint32_t SymbolBody::template getSize<ELF32LE>() const;
280 template uint32_t SymbolBody::template getSize<ELF32BE>() const;
281 template uint64_t SymbolBody::template getSize<ELF64LE>() const;
282 template uint64_t SymbolBody::template getSize<ELF64BE>() const;
283 
284 template int SymbolBody::compare<ELF32LE>(SymbolBody *Other);
285 template int SymbolBody::compare<ELF32BE>(SymbolBody *Other);
286 template int SymbolBody::compare<ELF64LE>(SymbolBody *Other);
287 template int SymbolBody::compare<ELF64BE>(SymbolBody *Other);
288 
289 template class elf::UndefinedElf<ELF32LE>;
290 template class elf::UndefinedElf<ELF32BE>;
291 template class elf::UndefinedElf<ELF64LE>;
292 template class elf::UndefinedElf<ELF64BE>;
293 
294 template class elf::DefinedSynthetic<ELF32LE>;
295 template class elf::DefinedSynthetic<ELF32BE>;
296 template class elf::DefinedSynthetic<ELF64LE>;
297 template class elf::DefinedSynthetic<ELF64BE>;
298