blob: f3c2a0eaf91aba208f9443a5b1eb98197b87ba3a [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 Ueyamaf829e8c2017-02-16 06:12:4182 if (SS.NeedsCopy)
83 return SS.Section->OutSec->Addr + SS.Section->OutSecOff;
Rui Ueyama924b3612017-02-16 06:12:2284 if (SS.NeedsPltAddr)
Rafael Espindola87d9f102016-03-11 12:19:0585 return Body.getPltVA<ELFT>();
Rui Ueyama924b3612017-02-16 06:12:2286 return 0;
Rui Ueyamab5a69702016-02-01 21:00:3587 }
Peter Collingbourne60976ed2016-04-27 00:05:0688 case SymbolBody::UndefinedKind:
Rui Ueyamab5a69702016-02-01 21:00:3589 return 0;
Rui Ueyamaf8baa662016-04-07 19:24:5190 case SymbolBody::LazyArchiveKind:
91 case SymbolBody::LazyObjectKind:
Peter Collingbourne4f952702016-05-01 04:55:0392 assert(Body.symbol()->IsUsedInRegularObj && "lazy symbol reached writer");
Rui Ueyamab5a69702016-02-01 21:00:3593 return 0;
94 }
George Rimar777f9632016-03-12 08:31:3495 llvm_unreachable("invalid symbol kind");
Rui Ueyamab5a69702016-02-01 21:00:3596}
97
Rui Ueyamaa13efc22016-11-29 18:05:0498SymbolBody::SymbolBody(Kind K, StringRefZ Name, bool IsLocal, uint8_t StOther,
99 uint8_t Type)
Rui Ueyama924b3612017-02-16 06:12:22100 : SymbolKind(K), NeedsCopy(false), NeedsPltAddr(false), IsLocal(IsLocal),
Peter Smithbaffdb82016-12-08 12:58:55101 IsInGlobalMipsGot(false), Is32BitMipsGot(false), IsInIplt(false),
Rui Ueyama924b3612017-02-16 06:12:22102 IsInIgot(false), Type(Type), StOther(StOther), Name(Name) {}
Rafael Espindolaf4765732016-04-06 13:22:41103
Rui Ueyamac4466602016-03-13 19:48:18104// Returns true if a symbol can be replaced at load-time by a symbol
105// with the same name defined in other ELF executable or DSO.
106bool SymbolBody::isPreemptible() const {
107 if (isLocal())
108 return false;
109
Rafael Espindola66434562016-05-05 19:41:49110 // Shared symbols resolve to the definition in the DSO. The exceptions are
111 // symbols with copy relocations (which resolve to .bss) or preempt plt
112 // entries (which resolve to that plt entry).
Rui Ueyamac4466602016-03-13 19:48:18113 if (isShared())
Rui Ueyama924b3612017-02-16 06:12:22114 return !NeedsCopy && !NeedsPltAddr;
Rui Ueyamac4466602016-03-13 19:48:18115
Peter Collingbourne66ac1d62016-04-22 20:21:26116 // That's all that can be preempted in a non-DSO.
Rui Ueyamac4466602016-03-13 19:48:18117 if (!Config->Shared)
118 return false;
Peter Collingbourne66ac1d62016-04-22 20:21:26119
Peter Collingbournedbe41872016-04-24 04:29:59120 // Only symbols that appear in dynsym can be preempted.
Peter Collingbourne4f952702016-05-01 04:55:03121 if (!symbol()->includeInDynsym())
Rui Ueyamac4466602016-03-13 19:48:18122 return false;
Peter Collingbourne66ac1d62016-04-22 20:21:26123
Rafael Espindola580d7a12016-07-07 22:50:54124 // Only default visibility symbols can be preempted.
125 if (symbol()->Visibility != STV_DEFAULT)
126 return false;
127
128 // -Bsymbolic means that definitions are not preempted.
Peter Collingbournedbe41872016-04-24 04:29:59129 if (Config->Bsymbolic || (Config->BsymbolicFunctions && isFunc()))
130 return !isDefined();
Rafael Espindola580d7a12016-07-07 22:50:54131 return true;
Rui Ueyamac4466602016-03-13 19:48:18132}
133
Rui Ueyamab5a69702016-02-01 21:00:35134template <class ELFT>
Rafael Espindola7386cea2017-02-16 00:12:34135typename ELFT::uint SymbolBody::getVA(int64_t Addend) const {
Rafael Espindola8381c562016-03-17 23:36:19136 typename ELFT::uint OutVA = getSymVA<ELFT>(*this, Addend);
137 return OutVA + Addend;
Rafael Espindola87d9f102016-03-11 12:19:05138}
139
Rui Ueyama9328b2c2016-03-14 23:16:09140template <class ELFT> typename ELFT::uint SymbolBody::getGotVA() const {
Eugene Leviantad4439e2016-11-11 11:33:32141 return In<ELFT>::Got->getVA() + getGotOffset<ELFT>();
Rafael Espindola74031ba2016-04-07 15:20:56142}
143
144template <class ELFT> typename ELFT::uint SymbolBody::getGotOffset() const {
Rui Ueyama803b1202016-07-13 18:55:14145 return GotIndex * Target->GotEntrySize;
Rui Ueyamab5a69702016-02-01 21:00:35146}
147
Rui Ueyama9328b2c2016-03-14 23:16:09148template <class ELFT> typename ELFT::uint SymbolBody::getGotPltVA() const {
Peter Smithbaffdb82016-12-08 12:58:55149 if (this->IsInIgot)
150 return In<ELFT>::IgotPlt->getVA() + getGotPltOffset<ELFT>();
Eugene Leviant41ca3272016-11-10 09:48:29151 return In<ELFT>::GotPlt->getVA() + getGotPltOffset<ELFT>();
Rafael Espindola74031ba2016-04-07 15:20:56152}
153
154template <class ELFT> typename ELFT::uint SymbolBody::getGotPltOffset() const {
Rui Ueyama803b1202016-07-13 18:55:14155 return GotPltIndex * Target->GotPltEntrySize;
Rui Ueyamab5a69702016-02-01 21:00:35156}
157
Rui Ueyama9328b2c2016-03-14 23:16:09158template <class ELFT> typename ELFT::uint SymbolBody::getPltVA() const {
Peter Smithbaffdb82016-12-08 12:58:55159 if (this->IsInIplt)
160 return In<ELFT>::Iplt->getVA() + PltIndex * Target->PltEntrySize;
Eugene Leviantff23d3e2016-11-18 14:35:03161 return In<ELFT>::Plt->getVA() + Target->PltHeaderSize +
Rui Ueyamab5a69702016-02-01 21:00:35162 PltIndex * Target->PltEntrySize;
163}
164
Rui Ueyama9328b2c2016-03-14 23:16:09165template <class ELFT> typename ELFT::uint SymbolBody::getSize() const {
Rafael Espindolae7553e42016-08-31 13:28:33166 if (const auto *C = dyn_cast<DefinedCommon>(this))
Rafael Espindolaccfe3cb2016-04-04 14:04:16167 return C->Size;
168 if (const auto *DR = dyn_cast<DefinedRegular<ELFT>>(this))
169 return DR->Size;
170 if (const auto *S = dyn_cast<SharedSymbol<ELFT>>(this))
171 return S->Sym.st_size;
Rui Ueyama512c61d2016-02-03 00:12:24172 return 0;
173}
174
Rui Ueyama35fa6c52016-11-23 05:48:40175// If a symbol name contains '@', the characters after that is
176// a symbol version name. This function parses that.
177void SymbolBody::parseSymbolVersion() {
178 StringRef S = getName();
179 size_t Pos = S.find('@');
180 if (Pos == 0 || Pos == StringRef::npos)
181 return;
182 StringRef Verstr = S.substr(Pos + 1);
183 if (Verstr.empty())
184 return;
185
186 // Truncate the symbol name so that it doesn't include the version string.
Rui Ueyamaa13efc22016-11-29 18:05:04187 Name = {S.data(), Pos};
Rui Ueyama35fa6c52016-11-23 05:48:40188
Rafael Espindola1d6d1b42017-01-17 16:08:06189 // If this is not in this DSO, it is not a definition.
190 if (!isInCurrentDSO())
Rafael Espindola2756e042017-01-06 22:30:35191 return;
192
Rui Ueyama35fa6c52016-11-23 05:48:40193 // '@@' in a symbol name means the default version.
194 // It is usually the most recent one.
195 bool IsDefault = (Verstr[0] == '@');
196 if (IsDefault)
197 Verstr = Verstr.substr(1);
198
199 for (VersionDefinition &Ver : Config->VersionDefinitions) {
200 if (Ver.Name != Verstr)
201 continue;
202
203 if (IsDefault)
204 symbol()->VersionId = Ver.Id;
205 else
206 symbol()->VersionId = Ver.Id | VERSYM_HIDDEN;
207 return;
208 }
209
210 // It is an error if the specified version is not defined.
Rui Ueyama44da9de2016-12-05 18:40:14211 error(toString(File) + ": symbol " + S + " has undefined version " + Verstr);
Rui Ueyama35fa6c52016-11-23 05:48:40212}
213
Rui Ueyamaa13efc22016-11-29 18:05:04214Defined::Defined(Kind K, StringRefZ Name, bool IsLocal, uint8_t StOther,
215 uint8_t Type)
216 : SymbolBody(K, Name, IsLocal, StOther, Type) {}
Rafael Espindola4d4b06a2015-12-24 00:47:42217
Simon Atanasyanf967f092016-09-29 12:58:36218template <class ELFT> bool DefinedRegular<ELFT>::isMipsPIC() const {
219 if (!Section || !isFunc())
220 return false;
221 return (this->StOther & STO_MIPS_MIPS16) == STO_MIPS_PIC ||
222 (Section->getFile()->getObj().getHeader()->e_flags & EF_MIPS_PIC);
223}
224
Peter Smith3a52eb02017-02-01 10:26:03225Undefined::Undefined(StringRefZ Name, bool IsLocal, uint8_t StOther,
226 uint8_t Type, InputFile *File)
Rui Ueyamaa13efc22016-11-29 18:05:04227 : SymbolBody(SymbolBody::UndefinedKind, Name, IsLocal, StOther, Type) {
Rui Ueyama434b5612016-07-17 03:11:46228 this->File = File;
229}
Rafael Espindola5d7593b2015-12-22 23:00:50230
Rui Ueyamaa13efc22016-11-29 18:05:04231DefinedCommon::DefinedCommon(StringRef Name, uint64_t Size, uint64_t Alignment,
Rafael Espindolae7553e42016-08-31 13:28:33232 uint8_t StOther, uint8_t Type, InputFile *File)
Rui Ueyamaa13efc22016-11-29 18:05:04233 : Defined(SymbolBody::DefinedCommonKind, Name, /*IsLocal=*/false, StOther,
234 Type),
Rui Ueyama2a7c1c12016-07-17 17:36:22235 Alignment(Alignment), Size(Size) {
236 this->File = File;
237}
Rafael Espindola11191912015-12-24 16:23:37238
Rui Ueyama55518e72016-10-28 20:57:25239InputFile *Lazy::fetch() {
Rui Ueyamaf8baa662016-04-07 19:24:51240 if (auto *S = dyn_cast<LazyArchive>(this))
Rui Ueyama55518e72016-10-28 20:57:25241 return S->fetch();
242 return cast<LazyObject>(this)->fetch();
Rui Ueyamaf8baa662016-04-07 19:24:51243}
244
Rui Ueyama434b5612016-07-17 03:11:46245LazyArchive::LazyArchive(ArchiveFile &File,
246 const llvm::object::Archive::Symbol S, uint8_t Type)
247 : Lazy(LazyArchiveKind, S.getName(), Type), Sym(S) {
248 this->File = &File;
249}
250
251LazyObject::LazyObject(StringRef Name, LazyObjectFile &File, uint8_t Type)
252 : Lazy(LazyObjectKind, Name, Type) {
253 this->File = &File;
254}
255
Rui Ueyama55518e72016-10-28 20:57:25256InputFile *LazyArchive::fetch() {
Davide Italianobcdd6c62016-10-12 19:35:54257 std::pair<MemoryBufferRef, uint64_t> MBInfo = file()->getMember(&Sym);
Michael J. Spencer1b348a62015-09-04 22:28:10258
259 // getMember returns an empty buffer if the member was already
260 // read from the library.
Davide Italianobcdd6c62016-10-12 19:35:54261 if (MBInfo.first.getBuffer().empty())
Rui Ueyama38dbd3e2016-09-14 00:05:51262 return nullptr;
Rui Ueyama55518e72016-10-28 20:57:25263 return createObjectFile(MBInfo.first, file()->getName(), MBInfo.second);
Michael J. Spencer1b348a62015-09-04 22:28:10264}
265
Rui Ueyama55518e72016-10-28 20:57:25266InputFile *LazyObject::fetch() {
Rui Ueyama434b5612016-07-17 03:11:46267 MemoryBufferRef MBRef = file()->getBuffer();
Rafael Espindola65c65ce2016-06-14 21:56:36268 if (MBRef.getBuffer().empty())
Rui Ueyama38dbd3e2016-09-14 00:05:51269 return nullptr;
Rui Ueyama55518e72016-10-28 20:57:25270 return createObjectFile(MBRef);
Rui Ueyamaf8baa662016-04-07 19:24:51271}
272
Rafael Espindolab7e2ee22017-01-10 17:08:13273uint8_t Symbol::computeBinding() const {
274 if (Config->Relocatable)
275 return Binding;
Peter Collingbournedadcc172016-04-22 18:42:48276 if (Visibility != STV_DEFAULT && Visibility != STV_PROTECTED)
Rafael Espindolab7e2ee22017-01-10 17:08:13277 return STB_LOCAL;
Rafael Espindola41a93a32017-01-16 17:35:23278 const SymbolBody *Body = body();
Rafael Espindola1d6d1b42017-01-17 16:08:06279 if (VersionId == VER_NDX_LOCAL && Body->isInCurrentDSO())
Rafael Espindolab7e2ee22017-01-10 17:08:13280 return STB_LOCAL;
281 if (Config->NoGnuUnique && Binding == STB_GNU_UNIQUE)
282 return STB_GLOBAL;
283 return Binding;
284}
285
286bool Symbol::includeInDynsym() const {
287 if (computeBinding() == STB_LOCAL)
Rafael Espindolaae605c12016-04-21 20:35:25288 return false;
Rafael Espindolab7e2ee22017-01-10 17:08:13289 return ExportDynamic || body()->isShared() ||
Peter Collingbourne4f952702016-05-01 04:55:03290 (body()->isUndefined() && Config->Shared);
Rafael Espindolaae605c12016-04-21 20:35:25291}
Rui Ueyama69c778c2016-07-17 17:50:09292
293// Print out a log message for --trace-symbol.
294void elf::printTraceSymbol(Symbol *Sym) {
295 SymbolBody *B = Sym->body();
Rui Ueyamae6e206d2017-02-21 23:22:56296 std::string S;
Rui Ueyama69c778c2016-07-17 17:50:09297 if (B->isUndefined())
Rui Ueyamae6e206d2017-02-21 23:22:56298 S = ": reference to ";
Rui Ueyama69c778c2016-07-17 17:50:09299 else if (B->isCommon())
Rui Ueyamae6e206d2017-02-21 23:22:56300 S = ": common definition of ";
Rui Ueyama69c778c2016-07-17 17:50:09301 else
Rui Ueyamae6e206d2017-02-21 23:22:56302 S = ": definition of ";
303
304 message(toString(B->File) + S + B->getName());
Rui Ueyama69c778c2016-07-17 17:50:09305}
306
Rui Ueyamaa3ac1732016-11-24 20:24:18307// Returns a symbol for an error message.
Rui Ueyamace039262017-01-06 10:04:08308std::string lld::toString(const SymbolBody &B) {
Rui Ueyamaa3ac1732016-11-24 20:24:18309 if (Config->Demangle)
Rui Ueyama4c5b8ce2016-12-07 23:17:05310 if (Optional<std::string> S = demangle(B.getName()))
311 return *S;
Rui Ueyamaa3ac1732016-11-24 20:24:18312 return B.getName();
313}
314
Rafael Espindola7386cea2017-02-16 00:12:34315template uint32_t SymbolBody::template getVA<ELF32LE>(int64_t) const;
316template uint32_t SymbolBody::template getVA<ELF32BE>(int64_t) const;
317template uint64_t SymbolBody::template getVA<ELF64LE>(int64_t) const;
318template uint64_t SymbolBody::template getVA<ELF64BE>(int64_t) const;
Rui Ueyamab5a69702016-02-01 21:00:35319
320template uint32_t SymbolBody::template getGotVA<ELF32LE>() const;
321template uint32_t SymbolBody::template getGotVA<ELF32BE>() const;
322template uint64_t SymbolBody::template getGotVA<ELF64LE>() const;
323template uint64_t SymbolBody::template getGotVA<ELF64BE>() const;
324
Rafael Espindola74031ba2016-04-07 15:20:56325template uint32_t SymbolBody::template getGotOffset<ELF32LE>() const;
326template uint32_t SymbolBody::template getGotOffset<ELF32BE>() const;
327template uint64_t SymbolBody::template getGotOffset<ELF64LE>() const;
328template uint64_t SymbolBody::template getGotOffset<ELF64BE>() const;
329
Rui Ueyamab5a69702016-02-01 21:00:35330template uint32_t SymbolBody::template getGotPltVA<ELF32LE>() const;
331template uint32_t SymbolBody::template getGotPltVA<ELF32BE>() const;
332template uint64_t SymbolBody::template getGotPltVA<ELF64LE>() const;
333template uint64_t SymbolBody::template getGotPltVA<ELF64BE>() const;
334
Rafael Espindola74031ba2016-04-07 15:20:56335template uint32_t SymbolBody::template getGotPltOffset<ELF32LE>() const;
336template uint32_t SymbolBody::template getGotPltOffset<ELF32BE>() const;
337template uint64_t SymbolBody::template getGotPltOffset<ELF64LE>() const;
338template uint64_t SymbolBody::template getGotPltOffset<ELF64BE>() const;
339
Rui Ueyamab5a69702016-02-01 21:00:35340template uint32_t SymbolBody::template getPltVA<ELF32LE>() const;
341template uint32_t SymbolBody::template getPltVA<ELF32BE>() const;
342template uint64_t SymbolBody::template getPltVA<ELF64LE>() const;
343template uint64_t SymbolBody::template getPltVA<ELF64BE>() const;
344
Rui Ueyama512c61d2016-02-03 00:12:24345template uint32_t SymbolBody::template getSize<ELF32LE>() const;
346template uint32_t SymbolBody::template getSize<ELF32BE>() const;
347template uint64_t SymbolBody::template getSize<ELF64LE>() const;
348template uint64_t SymbolBody::template getSize<ELF64BE>() const;
349
Peter Collingbournefeb6629d2017-01-10 01:21:50350template class elf::SharedSymbol<ELF32LE>;
351template class elf::SharedSymbol<ELF32BE>;
352template class elf::SharedSymbol<ELF64LE>;
353template class elf::SharedSymbol<ELF64BE>;
354
Simon Atanasyanf967f092016-09-29 12:58:36355template class elf::DefinedRegular<ELF32LE>;
356template class elf::DefinedRegular<ELF32BE>;
357template class elf::DefinedRegular<ELF64LE>;
358template class elf::DefinedRegular<ELF64BE>;