blob: 56e148a897ccb66fe3bf4c874fbb25e0eae6134e [file] [log] [blame]
Michael J. Spencer84487f12015-07-24 21:03:071//===- 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"
Rafael Espindola49a2ca62015-08-06 15:33:1911#include "Error.h"
Michael J. Spencercdae0a42015-07-28 22:58:2512#include "InputFiles.h"
Rui Ueyamab5a69702016-02-01 21:00:3513#include "InputSection.h"
14#include "OutputSections.h"
Rui Ueyamaa3ac1732016-11-24 20:24:1815#include "Strings.h"
Rui Ueyamae8a61022016-11-05 23:05:4716#include "SyntheticSections.h"
Rui Ueyamab5a69702016-02-01 21:00:3517#include "Target.h"
Rafael Espindola17cb7c02016-12-19 17:01:0118#include "Writer.h"
Michael J. Spencer84487f12015-07-24 21:03:0719
Michael J. Spencer1b348a62015-09-04 22:28:1020#include "llvm/ADT/STLExtras.h"
Eugene Leviantc958d8d2016-10-12 08:19:3021#include "llvm/Support/Path.h"
Rui Ueyamac72ba3a2016-11-23 04:57:2522#include <cstring>
Michael J. Spencer1b348a62015-09-04 22:28:1023
24using namespace llvm;
Michael J. Spencer84487f12015-07-24 21:03:0725using namespace llvm::object;
Rafael Espindola78471f02015-09-01 23:12:5226using namespace llvm::ELF;
Michael J. Spencer84487f12015-07-24 21:03:0727
28using namespace lld;
Rafael Espindolae0df00b2016-02-28 00:25:5429using namespace lld::elf;
Michael J. Spencer84487f12015-07-24 21:03:0730
Rui Ueyamab5a69702016-02-01 21:00:3531template <class ELFT>
Rafael Espindola7386cea2017-02-16 00:12:3432static typename ELFT::uint getSymVA(const SymbolBody &Body, int64_t &Addend) {
Rui Ueyama9328b2c2016-03-14 23:16:0933 typedef typename ELFT::uint uintX_t;
Rafael Espindola87d9f102016-03-11 12:19:0534
35 switch (Body.kind()) {
36 case SymbolBody::DefinedSyntheticKind: {
Rui Ueyama4f2f50d2016-12-21 08:40:0937 auto &D = cast<DefinedSynthetic>(Body);
Rafael Espindolae08e78d2016-11-09 23:23:4538 const OutputSectionBase *Sec = D.Section;
Peter Collingbourne6a422592016-05-03 01:21:0839 if (!Sec)
40 return D.Value;
Rui Ueyama4f2f50d2016-12-21 08:40:0941 if (D.Value == uintX_t(-1))
Rafael Espindola04a2e342016-11-09 01:42:4142 return Sec->Addr + Sec->Size;
43 return Sec->Addr + D.Value;
Rui Ueyamab5a69702016-02-01 21:00:3544 }
Rafael Espindola87d9f102016-03-11 12:19:0545 case SymbolBody::DefinedRegularKind: {
46 auto &D = cast<DefinedRegular<ELFT>>(Body);
Sean Silva902ae3c2016-12-15 00:57:5347 InputSectionBase<ELFT> *IS = D.Section;
Rui Ueyamab5a69702016-02-01 21:00:3548
Rafael Espindolaccfe3cb2016-04-04 14:04:1649 // 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.
Sean Silva902ae3c2016-12-15 00:57:5353 if (IS == &InputSection<ELFT>::Discarded)
Rafael Espindolaccfe3cb2016-04-04 14:04:1654 return 0;
55
Rui Ueyamab5a69702016-02-01 21:00:3556 // This is an absolute symbol.
Sean Silva902ae3c2016-12-15 00:57:5357 if (!IS)
Rafael Espindolaccfe3cb2016-04-04 14:04:1658 return D.Value;
Rui Ueyamab5a69702016-02-01 21:00:3559
Rafael Espindolaccfe3cb2016-04-04 14:04:1660 uintX_t Offset = D.Value;
61 if (D.isSection()) {
Rafael Espindola1f5b70f2016-03-11 14:21:3762 Offset += Addend;
63 Addend = 0;
64 }
Rafael Espindola9e9754b2017-02-03 13:06:1865 const OutputSectionBase *OutSec = IS->getOutputSection();
66 uintX_t VA = (OutSec ? OutSec->Addr : 0) + IS->getOffset(Offset);
George Rimar6a3b1542016-10-04 08:52:5167 if (D.isTls() && !Config->Relocatable) {
68 if (!Out<ELFT>::TlsPhdr)
Rui Ueyama3fc0f7e2016-11-23 18:07:3369 fatal(toString(D.File) +
George Rimar6a3b1542016-10-04 08:52:5170 " has a STT_TLS symbol but doesn't have a PT_TLS section");
Rafael Espindola1f5b70f2016-03-11 14:21:3771 return VA - Out<ELFT>::TlsPhdr->p_vaddr;
George Rimar6a3b1542016-10-04 08:52:5172 }
Rafael Espindola1f5b70f2016-03-11 14:21:3773 return VA;
Rui Ueyamab5a69702016-02-01 21:00:3574 }
Rui Ueyama07784902016-08-02 01:35:1375 case SymbolBody::DefinedCommonKind:
Rui Ueyamab2a23cf2017-01-24 03:41:2076 if (!Config->DefineCommon)
77 return 0;
Rafael Espindola04a2e342016-11-09 01:42:4178 return In<ELFT>::Common->OutSec->Addr + In<ELFT>::Common->OutSecOff +
Rafael Espindolae7553e42016-08-31 13:28:3379 cast<DefinedCommon>(Body).Offset;
Rafael Espindola87d9f102016-03-11 12:19:0580 case SymbolBody::SharedKind: {
81 auto &SS = cast<SharedSymbol<ELFT>>(Body);
Rui Ueyama924b3612017-02-16 06:12:2282 if (SS.NeedsCopy) {
83 InputSection<ELFT> *ISec = SS.getBssSectionForCopy();
84 return ISec->OutSec->Addr + ISec->OutSecOff;
85 }
86 if (SS.NeedsPltAddr)
Rafael Espindola87d9f102016-03-11 12:19:0587 return Body.getPltVA<ELFT>();
Rui Ueyama924b3612017-02-16 06:12:2288 return 0;
Rui Ueyamab5a69702016-02-01 21:00:3589 }
Peter Collingbourne60976ed2016-04-27 00:05:0690 case SymbolBody::UndefinedKind:
Rui Ueyamab5a69702016-02-01 21:00:3591 return 0;
Rui Ueyamaf8baa662016-04-07 19:24:5192 case SymbolBody::LazyArchiveKind:
93 case SymbolBody::LazyObjectKind:
Peter Collingbourne4f952702016-05-01 04:55:0394 assert(Body.symbol()->IsUsedInRegularObj && "lazy symbol reached writer");
Rui Ueyamab5a69702016-02-01 21:00:3595 return 0;
96 }
George Rimar777f9632016-03-12 08:31:3497 llvm_unreachable("invalid symbol kind");
Rui Ueyamab5a69702016-02-01 21:00:3598}
99
Rui Ueyamaa13efc22016-11-29 18:05:04100SymbolBody::SymbolBody(Kind K, StringRefZ Name, bool IsLocal, uint8_t StOther,
101 uint8_t Type)
Rui Ueyama924b3612017-02-16 06:12:22102 : SymbolKind(K), NeedsCopy(false), NeedsPltAddr(false), IsLocal(IsLocal),
Peter Smithbaffdb82016-12-08 12:58:55103 IsInGlobalMipsGot(false), Is32BitMipsGot(false), IsInIplt(false),
Rui Ueyama924b3612017-02-16 06:12:22104 IsInIgot(false), Type(Type), StOther(StOther), Name(Name) {}
Rafael Espindolaf4765732016-04-06 13:22:41105
Rui Ueyamac4466602016-03-13 19:48:18106// Returns true if a symbol can be replaced at load-time by a symbol
107// with the same name defined in other ELF executable or DSO.
108bool SymbolBody::isPreemptible() const {
109 if (isLocal())
110 return false;
111
Rafael Espindola66434562016-05-05 19:41:49112 // Shared symbols resolve to the definition in the DSO. The exceptions are
113 // symbols with copy relocations (which resolve to .bss) or preempt plt
114 // entries (which resolve to that plt entry).
Rui Ueyamac4466602016-03-13 19:48:18115 if (isShared())
Rui Ueyama924b3612017-02-16 06:12:22116 return !NeedsCopy && !NeedsPltAddr;
Rui Ueyamac4466602016-03-13 19:48:18117
Peter Collingbourne66ac1d62016-04-22 20:21:26118 // That's all that can be preempted in a non-DSO.
Rui Ueyamac4466602016-03-13 19:48:18119 if (!Config->Shared)
120 return false;
Peter Collingbourne66ac1d62016-04-22 20:21:26121
Peter Collingbournedbe41872016-04-24 04:29:59122 // Only symbols that appear in dynsym can be preempted.
Peter Collingbourne4f952702016-05-01 04:55:03123 if (!symbol()->includeInDynsym())
Rui Ueyamac4466602016-03-13 19:48:18124 return false;
Peter Collingbourne66ac1d62016-04-22 20:21:26125
Rafael Espindola580d7a12016-07-07 22:50:54126 // Only default visibility symbols can be preempted.
127 if (symbol()->Visibility != STV_DEFAULT)
128 return false;
129
130 // -Bsymbolic means that definitions are not preempted.
Peter Collingbournedbe41872016-04-24 04:29:59131 if (Config->Bsymbolic || (Config->BsymbolicFunctions && isFunc()))
132 return !isDefined();
Rafael Espindola580d7a12016-07-07 22:50:54133 return true;
Rui Ueyamac4466602016-03-13 19:48:18134}
135
Rui Ueyamab5a69702016-02-01 21:00:35136template <class ELFT>
Rafael Espindola7386cea2017-02-16 00:12:34137typename ELFT::uint SymbolBody::getVA(int64_t Addend) const {
Rafael Espindola8381c562016-03-17 23:36:19138 typename ELFT::uint OutVA = getSymVA<ELFT>(*this, Addend);
139 return OutVA + Addend;
Rafael Espindola87d9f102016-03-11 12:19:05140}
141
Rui Ueyama9328b2c2016-03-14 23:16:09142template <class ELFT> typename ELFT::uint SymbolBody::getGotVA() const {
Eugene Leviantad4439e2016-11-11 11:33:32143 return In<ELFT>::Got->getVA() + getGotOffset<ELFT>();
Rafael Espindola74031ba2016-04-07 15:20:56144}
145
146template <class ELFT> typename ELFT::uint SymbolBody::getGotOffset() const {
Rui Ueyama803b1202016-07-13 18:55:14147 return GotIndex * Target->GotEntrySize;
Rui Ueyamab5a69702016-02-01 21:00:35148}
149
Rui Ueyama9328b2c2016-03-14 23:16:09150template <class ELFT> typename ELFT::uint SymbolBody::getGotPltVA() const {
Peter Smithbaffdb82016-12-08 12:58:55151 if (this->IsInIgot)
152 return In<ELFT>::IgotPlt->getVA() + getGotPltOffset<ELFT>();
Eugene Leviant41ca3272016-11-10 09:48:29153 return In<ELFT>::GotPlt->getVA() + getGotPltOffset<ELFT>();
Rafael Espindola74031ba2016-04-07 15:20:56154}
155
156template <class ELFT> typename ELFT::uint SymbolBody::getGotPltOffset() const {
Rui Ueyama803b1202016-07-13 18:55:14157 return GotPltIndex * Target->GotPltEntrySize;
Rui Ueyamab5a69702016-02-01 21:00:35158}
159
Rui Ueyama9328b2c2016-03-14 23:16:09160template <class ELFT> typename ELFT::uint SymbolBody::getPltVA() const {
Peter Smithbaffdb82016-12-08 12:58:55161 if (this->IsInIplt)
162 return In<ELFT>::Iplt->getVA() + PltIndex * Target->PltEntrySize;
Eugene Leviantff23d3e2016-11-18 14:35:03163 return In<ELFT>::Plt->getVA() + Target->PltHeaderSize +
Rui Ueyamab5a69702016-02-01 21:00:35164 PltIndex * Target->PltEntrySize;
165}
166
Rui Ueyama9328b2c2016-03-14 23:16:09167template <class ELFT> typename ELFT::uint SymbolBody::getSize() const {
Rafael Espindolae7553e42016-08-31 13:28:33168 if (const auto *C = dyn_cast<DefinedCommon>(this))
Rafael Espindolaccfe3cb2016-04-04 14:04:16169 return C->Size;
170 if (const auto *DR = dyn_cast<DefinedRegular<ELFT>>(this))
171 return DR->Size;
172 if (const auto *S = dyn_cast<SharedSymbol<ELFT>>(this))
173 return S->Sym.st_size;
Rui Ueyama512c61d2016-02-03 00:12:24174 return 0;
175}
176
Rui Ueyama35fa6c52016-11-23 05:48:40177// If a symbol name contains '@', the characters after that is
178// a symbol version name. This function parses that.
179void SymbolBody::parseSymbolVersion() {
180 StringRef S = getName();
181 size_t Pos = S.find('@');
182 if (Pos == 0 || Pos == StringRef::npos)
183 return;
184 StringRef Verstr = S.substr(Pos + 1);
185 if (Verstr.empty())
186 return;
187
188 // Truncate the symbol name so that it doesn't include the version string.
Rui Ueyamaa13efc22016-11-29 18:05:04189 Name = {S.data(), Pos};
Rui Ueyama35fa6c52016-11-23 05:48:40190
Rafael Espindola1d6d1b42017-01-17 16:08:06191 // If this is not in this DSO, it is not a definition.
192 if (!isInCurrentDSO())
Rafael Espindola2756e042017-01-06 22:30:35193 return;
194
Rui Ueyama35fa6c52016-11-23 05:48:40195 // '@@' in a symbol name means the default version.
196 // It is usually the most recent one.
197 bool IsDefault = (Verstr[0] == '@');
198 if (IsDefault)
199 Verstr = Verstr.substr(1);
200
201 for (VersionDefinition &Ver : Config->VersionDefinitions) {
202 if (Ver.Name != Verstr)
203 continue;
204
205 if (IsDefault)
206 symbol()->VersionId = Ver.Id;
207 else
208 symbol()->VersionId = Ver.Id | VERSYM_HIDDEN;
209 return;
210 }
211
212 // It is an error if the specified version is not defined.
Rui Ueyama44da9de2016-12-05 18:40:14213 error(toString(File) + ": symbol " + S + " has undefined version " + Verstr);
Rui Ueyama35fa6c52016-11-23 05:48:40214}
215
Rui Ueyamaa13efc22016-11-29 18:05:04216Defined::Defined(Kind K, StringRefZ Name, bool IsLocal, uint8_t StOther,
217 uint8_t Type)
218 : SymbolBody(K, Name, IsLocal, StOther, Type) {}
Rafael Espindola4d4b06a2015-12-24 00:47:42219
Simon Atanasyanf967f092016-09-29 12:58:36220template <class ELFT> bool DefinedRegular<ELFT>::isMipsPIC() const {
221 if (!Section || !isFunc())
222 return false;
223 return (this->StOther & STO_MIPS_MIPS16) == STO_MIPS_PIC ||
224 (Section->getFile()->getObj().getHeader()->e_flags & EF_MIPS_PIC);
225}
226
Peter Smith3a52eb02017-02-01 10:26:03227Undefined::Undefined(StringRefZ Name, bool IsLocal, uint8_t StOther,
228 uint8_t Type, InputFile *File)
Rui Ueyamaa13efc22016-11-29 18:05:04229 : SymbolBody(SymbolBody::UndefinedKind, Name, IsLocal, StOther, Type) {
Rui Ueyama434b5612016-07-17 03:11:46230 this->File = File;
231}
Rafael Espindola5d7593b2015-12-22 23:00:50232
Peter Collingbournefeb6629d2017-01-10 01:21:50233template <typename ELFT>
Peter Smithebfe9942017-02-09 10:27:57234InputSection<ELFT> *SharedSymbol<ELFT>::getBssSectionForCopy() const {
Rui Ueyama924b3612017-02-16 06:12:22235 assert(NeedsCopy);
Peter Smithebfe9942017-02-09 10:27:57236 assert(CopySection);
237 return CopySection;
Peter Collingbournefeb6629d2017-01-10 01:21:50238}
239
Rui Ueyamaa13efc22016-11-29 18:05:04240DefinedCommon::DefinedCommon(StringRef Name, uint64_t Size, uint64_t Alignment,
Rafael Espindolae7553e42016-08-31 13:28:33241 uint8_t StOther, uint8_t Type, InputFile *File)
Rui Ueyamaa13efc22016-11-29 18:05:04242 : Defined(SymbolBody::DefinedCommonKind, Name, /*IsLocal=*/false, StOther,
243 Type),
Rui Ueyama2a7c1c12016-07-17 17:36:22244 Alignment(Alignment), Size(Size) {
245 this->File = File;
246}
Rafael Espindola11191912015-12-24 16:23:37247
Rui Ueyama55518e72016-10-28 20:57:25248InputFile *Lazy::fetch() {
Rui Ueyamaf8baa662016-04-07 19:24:51249 if (auto *S = dyn_cast<LazyArchive>(this))
Rui Ueyama55518e72016-10-28 20:57:25250 return S->fetch();
251 return cast<LazyObject>(this)->fetch();
Rui Ueyamaf8baa662016-04-07 19:24:51252}
253
Rui Ueyama434b5612016-07-17 03:11:46254LazyArchive::LazyArchive(ArchiveFile &File,
255 const llvm::object::Archive::Symbol S, uint8_t Type)
256 : Lazy(LazyArchiveKind, S.getName(), Type), Sym(S) {
257 this->File = &File;
258}
259
260LazyObject::LazyObject(StringRef Name, LazyObjectFile &File, uint8_t Type)
261 : Lazy(LazyObjectKind, Name, Type) {
262 this->File = &File;
263}
264
Rui Ueyama55518e72016-10-28 20:57:25265InputFile *LazyArchive::fetch() {
Davide Italianobcdd6c62016-10-12 19:35:54266 std::pair<MemoryBufferRef, uint64_t> MBInfo = file()->getMember(&Sym);
Michael J. Spencer1b348a62015-09-04 22:28:10267
268 // getMember returns an empty buffer if the member was already
269 // read from the library.
Davide Italianobcdd6c62016-10-12 19:35:54270 if (MBInfo.first.getBuffer().empty())
Rui Ueyama38dbd3e2016-09-14 00:05:51271 return nullptr;
Rui Ueyama55518e72016-10-28 20:57:25272 return createObjectFile(MBInfo.first, file()->getName(), MBInfo.second);
Michael J. Spencer1b348a62015-09-04 22:28:10273}
274
Rui Ueyama55518e72016-10-28 20:57:25275InputFile *LazyObject::fetch() {
Rui Ueyama434b5612016-07-17 03:11:46276 MemoryBufferRef MBRef = file()->getBuffer();
Rafael Espindola65c65ce2016-06-14 21:56:36277 if (MBRef.getBuffer().empty())
Rui Ueyama38dbd3e2016-09-14 00:05:51278 return nullptr;
Rui Ueyama55518e72016-10-28 20:57:25279 return createObjectFile(MBRef);
Rui Ueyamaf8baa662016-04-07 19:24:51280}
281
Rafael Espindolab7e2ee22017-01-10 17:08:13282uint8_t Symbol::computeBinding() const {
283 if (Config->Relocatable)
284 return Binding;
Peter Collingbournedadcc172016-04-22 18:42:48285 if (Visibility != STV_DEFAULT && Visibility != STV_PROTECTED)
Rafael Espindolab7e2ee22017-01-10 17:08:13286 return STB_LOCAL;
Rafael Espindola41a93a32017-01-16 17:35:23287 const SymbolBody *Body = body();
Rafael Espindola1d6d1b42017-01-17 16:08:06288 if (VersionId == VER_NDX_LOCAL && Body->isInCurrentDSO())
Rafael Espindolab7e2ee22017-01-10 17:08:13289 return STB_LOCAL;
290 if (Config->NoGnuUnique && Binding == STB_GNU_UNIQUE)
291 return STB_GLOBAL;
292 return Binding;
293}
294
295bool Symbol::includeInDynsym() const {
296 if (computeBinding() == STB_LOCAL)
Rafael Espindolaae605c12016-04-21 20:35:25297 return false;
Rafael Espindolab7e2ee22017-01-10 17:08:13298 return ExportDynamic || body()->isShared() ||
Peter Collingbourne4f952702016-05-01 04:55:03299 (body()->isUndefined() && Config->Shared);
Rafael Espindolaae605c12016-04-21 20:35:25300}
Rui Ueyama69c778c2016-07-17 17:50:09301
302// Print out a log message for --trace-symbol.
303void elf::printTraceSymbol(Symbol *Sym) {
304 SymbolBody *B = Sym->body();
Rui Ueyama3fc0f7e2016-11-23 18:07:33305 outs() << toString(B->File);
Rui Ueyama69c778c2016-07-17 17:50:09306
307 if (B->isUndefined())
308 outs() << ": reference to ";
309 else if (B->isCommon())
310 outs() << ": common definition of ";
311 else
312 outs() << ": definition of ";
313 outs() << B->getName() << "\n";
314}
315
Rui Ueyamaa3ac1732016-11-24 20:24:18316// Returns a symbol for an error message.
Rui Ueyamace039262017-01-06 10:04:08317std::string lld::toString(const SymbolBody &B) {
Rui Ueyamaa3ac1732016-11-24 20:24:18318 if (Config->Demangle)
Rui Ueyama4c5b8ce2016-12-07 23:17:05319 if (Optional<std::string> S = demangle(B.getName()))
320 return *S;
Rui Ueyamaa3ac1732016-11-24 20:24:18321 return B.getName();
322}
323
Rafael Espindola7386cea2017-02-16 00:12:34324template uint32_t SymbolBody::template getVA<ELF32LE>(int64_t) const;
325template uint32_t SymbolBody::template getVA<ELF32BE>(int64_t) const;
326template uint64_t SymbolBody::template getVA<ELF64LE>(int64_t) const;
327template uint64_t SymbolBody::template getVA<ELF64BE>(int64_t) const;
Rui Ueyamab5a69702016-02-01 21:00:35328
329template uint32_t SymbolBody::template getGotVA<ELF32LE>() const;
330template uint32_t SymbolBody::template getGotVA<ELF32BE>() const;
331template uint64_t SymbolBody::template getGotVA<ELF64LE>() const;
332template uint64_t SymbolBody::template getGotVA<ELF64BE>() const;
333
Rafael Espindola74031ba2016-04-07 15:20:56334template uint32_t SymbolBody::template getGotOffset<ELF32LE>() const;
335template uint32_t SymbolBody::template getGotOffset<ELF32BE>() const;
336template uint64_t SymbolBody::template getGotOffset<ELF64LE>() const;
337template uint64_t SymbolBody::template getGotOffset<ELF64BE>() const;
338
Rui Ueyamab5a69702016-02-01 21:00:35339template uint32_t SymbolBody::template getGotPltVA<ELF32LE>() const;
340template uint32_t SymbolBody::template getGotPltVA<ELF32BE>() const;
341template uint64_t SymbolBody::template getGotPltVA<ELF64LE>() const;
342template uint64_t SymbolBody::template getGotPltVA<ELF64BE>() const;
343
Rafael Espindola74031ba2016-04-07 15:20:56344template uint32_t SymbolBody::template getGotPltOffset<ELF32LE>() const;
345template uint32_t SymbolBody::template getGotPltOffset<ELF32BE>() const;
346template uint64_t SymbolBody::template getGotPltOffset<ELF64LE>() const;
347template uint64_t SymbolBody::template getGotPltOffset<ELF64BE>() const;
348
Rui Ueyamab5a69702016-02-01 21:00:35349template uint32_t SymbolBody::template getPltVA<ELF32LE>() const;
350template uint32_t SymbolBody::template getPltVA<ELF32BE>() const;
351template uint64_t SymbolBody::template getPltVA<ELF64LE>() const;
352template uint64_t SymbolBody::template getPltVA<ELF64BE>() const;
353
Rui Ueyama512c61d2016-02-03 00:12:24354template uint32_t SymbolBody::template getSize<ELF32LE>() const;
355template uint32_t SymbolBody::template getSize<ELF32BE>() const;
356template uint64_t SymbolBody::template getSize<ELF64LE>() const;
357template uint64_t SymbolBody::template getSize<ELF64BE>() const;
358
Peter Collingbournefeb6629d2017-01-10 01:21:50359template class elf::SharedSymbol<ELF32LE>;
360template class elf::SharedSymbol<ELF32BE>;
361template class elf::SharedSymbol<ELF64LE>;
362template class elf::SharedSymbol<ELF64BE>;
363
Simon Atanasyanf967f092016-09-29 12:58:36364template class elf::DefinedRegular<ELF32LE>;
365template class elf::DefinedRegular<ELF32BE>;
366template class elf::DefinedRegular<ELF64LE>;
367template class elf::DefinedRegular<ELF64BE>;