]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/tools/lld/ELF/Symbols.cpp
Update compiler-rt to release_39 branch r288513. Since this contains a
[FreeBSD/FreeBSD.git] / contrib / llvm / tools / lld / ELF / Symbols.cpp
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
19 using namespace llvm;
20 using namespace llvm::object;
21 using namespace llvm::ELF;
22
23 using namespace lld;
24 using namespace lld::elf;
25
26 template <class ELFT>
27 static 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
88 SymbolBody::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
94 SymbolBody::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
99 StringRef SymbolBody::getName() const {
100   assert(!isLocal());
101   return StringRef(Name.S, Name.Len);
102 }
103
104 void 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.
111 bool 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
139 template <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
147 template <class ELFT>
148 typename ELFT::uint SymbolBody::getVA(typename ELFT::uint Addend) const {
149   typename ELFT::uint OutVA = getSymVA<ELFT>(*this, Addend);
150   return OutVA + Addend;
151 }
152
153 template <class ELFT> typename ELFT::uint SymbolBody::getGotVA() const {
154   return Out<ELFT>::Got->getVA() + getGotOffset<ELFT>();
155 }
156
157 template <class ELFT> typename ELFT::uint SymbolBody::getGotOffset() const {
158   return GotIndex * Target->GotEntrySize;
159 }
160
161 template <class ELFT> typename ELFT::uint SymbolBody::getGotPltVA() const {
162   return Out<ELFT>::GotPlt->getVA() + getGotPltOffset<ELFT>();
163 }
164
165 template <class ELFT> typename ELFT::uint SymbolBody::getGotPltOffset() const {
166   return GotPltIndex * Target->GotPltEntrySize;
167 }
168
169 template <class ELFT> typename ELFT::uint SymbolBody::getPltVA() const {
170   return Out<ELFT>::Plt->getVA() + Target->PltHeaderSize +
171          PltIndex * Target->PltEntrySize;
172 }
173
174 template <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
182 template <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
192 Defined::Defined(Kind K, StringRef Name, uint8_t StOther, uint8_t Type)
193     : SymbolBody(K, Name, StOther, Type) {}
194
195 Defined::Defined(Kind K, uint32_t NameOffset, uint8_t StOther, uint8_t Type)
196     : SymbolBody(K, NameOffset, StOther, Type) {}
197
198 DefinedBitcode::DefinedBitcode(StringRef Name, uint8_t StOther, uint8_t Type,
199                                BitcodeFile *F)
200     : Defined(DefinedBitcodeKind, Name, StOther, Type) {
201   this->File = F;
202 }
203
204 bool DefinedBitcode::classof(const SymbolBody *S) {
205   return S->kind() == DefinedBitcodeKind;
206 }
207
208 Undefined::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
214 Undefined::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
220 template <typename ELFT>
221 DefinedSynthetic<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
226 DefinedCommon::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
233 std::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
239 LazyArchive::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
245 LazyObject::LazyObject(StringRef Name, LazyObjectFile &File, uint8_t Type)
246     : Lazy(LazyObjectKind, Name, Type) {
247   this->File = &File;
248 }
249
250 std::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
260 std::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
267 bool 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.
275 void 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
288 template bool SymbolBody::hasThunk<ELF32LE>() const;
289 template bool SymbolBody::hasThunk<ELF32BE>() const;
290 template bool SymbolBody::hasThunk<ELF64LE>() const;
291 template bool SymbolBody::hasThunk<ELF64BE>() const;
292
293 template uint32_t SymbolBody::template getVA<ELF32LE>(uint32_t) const;
294 template uint32_t SymbolBody::template getVA<ELF32BE>(uint32_t) const;
295 template uint64_t SymbolBody::template getVA<ELF64LE>(uint64_t) const;
296 template uint64_t SymbolBody::template getVA<ELF64BE>(uint64_t) const;
297
298 template uint32_t SymbolBody::template getGotVA<ELF32LE>() const;
299 template uint32_t SymbolBody::template getGotVA<ELF32BE>() const;
300 template uint64_t SymbolBody::template getGotVA<ELF64LE>() const;
301 template uint64_t SymbolBody::template getGotVA<ELF64BE>() const;
302
303 template uint32_t SymbolBody::template getGotOffset<ELF32LE>() const;
304 template uint32_t SymbolBody::template getGotOffset<ELF32BE>() const;
305 template uint64_t SymbolBody::template getGotOffset<ELF64LE>() const;
306 template uint64_t SymbolBody::template getGotOffset<ELF64BE>() const;
307
308 template uint32_t SymbolBody::template getGotPltVA<ELF32LE>() const;
309 template uint32_t SymbolBody::template getGotPltVA<ELF32BE>() const;
310 template uint64_t SymbolBody::template getGotPltVA<ELF64LE>() const;
311 template uint64_t SymbolBody::template getGotPltVA<ELF64BE>() const;
312
313 template uint32_t SymbolBody::template getThunkVA<ELF32LE>() const;
314 template uint32_t SymbolBody::template getThunkVA<ELF32BE>() const;
315 template uint64_t SymbolBody::template getThunkVA<ELF64LE>() const;
316 template uint64_t SymbolBody::template getThunkVA<ELF64BE>() const;
317
318 template uint32_t SymbolBody::template getGotPltOffset<ELF32LE>() const;
319 template uint32_t SymbolBody::template getGotPltOffset<ELF32BE>() const;
320 template uint64_t SymbolBody::template getGotPltOffset<ELF64LE>() const;
321 template uint64_t SymbolBody::template getGotPltOffset<ELF64BE>() const;
322
323 template uint32_t SymbolBody::template getPltVA<ELF32LE>() const;
324 template uint32_t SymbolBody::template getPltVA<ELF32BE>() const;
325 template uint64_t SymbolBody::template getPltVA<ELF64LE>() const;
326 template uint64_t SymbolBody::template getPltVA<ELF64BE>() const;
327
328 template uint32_t SymbolBody::template getSize<ELF32LE>() const;
329 template uint32_t SymbolBody::template getSize<ELF32BE>() const;
330 template uint64_t SymbolBody::template getSize<ELF64LE>() const;
331 template uint64_t SymbolBody::template getSize<ELF64BE>() const;
332
333 template class elf::DefinedSynthetic<ELF32LE>;
334 template class elf::DefinedSynthetic<ELF32BE>;
335 template class elf::DefinedSynthetic<ELF64LE>;
336 template class elf::DefinedSynthetic<ELF64BE>;