1 //===- OutputSections.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 "OutputSections.h" 11 #include "Config.h" 12 #include "SymbolTable.h" 13 #include "Target.h" 14 15 using namespace llvm; 16 using namespace llvm::object; 17 using namespace llvm::ELF; 18 19 using namespace lld; 20 using namespace lld::elf2; 21 22 template <bool Is64Bits> 23 OutputSectionBase<Is64Bits>::OutputSectionBase(StringRef Name, uint32_t sh_type, 24 uintX_t sh_flags) 25 : Name(Name) { 26 memset(&Header, 0, sizeof(HeaderT)); 27 Header.sh_type = sh_type; 28 Header.sh_flags = sh_flags; 29 } 30 31 template <class ELFT> 32 GotSection<ELFT>::GotSection() 33 : OutputSectionBase<ELFT::Is64Bits>(".got", llvm::ELF::SHT_PROGBITS, 34 llvm::ELF::SHF_ALLOC | 35 llvm::ELF::SHF_WRITE) { 36 this->Header.sh_addralign = this->getAddrSize(); 37 } 38 39 template <class ELFT> void GotSection<ELFT>::addEntry(SymbolBody *Sym) { 40 Sym->setGotIndex(Entries.size()); 41 Entries.push_back(Sym); 42 } 43 44 template <class ELFT> 45 typename GotSection<ELFT>::uintX_t 46 GotSection<ELFT>::getEntryAddr(const SymbolBody &B) const { 47 return this->getVA() + B.getGotIndex() * this->getAddrSize(); 48 } 49 50 template <class ELFT> 51 PltSection<ELFT>::PltSection(const GotSection<ELFT> &GotSec) 52 : OutputSectionBase<ELFT::Is64Bits>(".plt", llvm::ELF::SHT_PROGBITS, 53 llvm::ELF::SHF_ALLOC | 54 llvm::ELF::SHF_EXECINSTR), 55 GotSec(GotSec) { 56 this->Header.sh_addralign = 16; 57 } 58 59 template <class ELFT> void PltSection<ELFT>::writeTo(uint8_t *Buf) { 60 uintptr_t Start = reinterpret_cast<uintptr_t>(Buf); 61 for (const SymbolBody *E : Entries) { 62 uint64_t GotEntryAddr = GotSec.getEntryAddr(*E); 63 uintptr_t InstPos = reinterpret_cast<uintptr_t>(Buf); 64 uint64_t PltEntryAddr = (InstPos - Start) + this->getVA(); 65 Target->writePltEntry(Buf, GotEntryAddr, PltEntryAddr); 66 Buf += 8; 67 } 68 } 69 70 template <class ELFT> void PltSection<ELFT>::addEntry(SymbolBody *Sym) { 71 Sym->setPltIndex(Entries.size()); 72 Entries.push_back(Sym); 73 } 74 75 template <class ELFT> 76 typename PltSection<ELFT>::uintX_t 77 PltSection<ELFT>::getEntryAddr(const SymbolBody &B) const { 78 return this->getVA() + B.getPltIndex() * EntrySize; 79 } 80 81 template <class ELFT> 82 RelocationSection<ELFT>::RelocationSection(SymbolTableSection<ELFT> &DynSymSec, 83 const GotSection<ELFT> &GotSec, 84 bool IsRela) 85 : OutputSectionBase<ELFT::Is64Bits>(IsRela ? ".rela.dyn" : ".rel.dyn", 86 IsRela ? llvm::ELF::SHT_RELA 87 : llvm::ELF::SHT_REL, 88 llvm::ELF::SHF_ALLOC), 89 DynSymSec(DynSymSec), GotSec(GotSec), IsRela(IsRela) { 90 this->Header.sh_entsize = IsRela ? sizeof(Elf_Rela) : sizeof(Elf_Rel); 91 this->Header.sh_addralign = ELFT::Is64Bits ? 8 : 4; 92 } 93 94 template <class ELFT> void RelocationSection<ELFT>::writeTo(uint8_t *Buf) { 95 const unsigned EntrySize = IsRela ? sizeof(Elf_Rela) : sizeof(Elf_Rel); 96 bool IsMips64EL = Relocs[0].C.getFile()->getObj().isMips64EL(); 97 for (const DynamicReloc<ELFT> &Rel : Relocs) { 98 auto *P = reinterpret_cast<Elf_Rel *>(Buf); 99 Buf += EntrySize; 100 101 const InputSection<ELFT> &C = Rel.C; 102 const Elf_Rel &RI = Rel.RI; 103 OutputSection<ELFT> *Out = C.getOutputSection(); 104 uint32_t SymIndex = RI.getSymbol(IsMips64EL); 105 const SymbolBody *Body = C.getFile()->getSymbolBody(SymIndex); 106 uint32_t Type = RI.getType(IsMips64EL); 107 if (Target->relocNeedsGot(Type, *Body)) { 108 P->r_offset = GotSec.getEntryAddr(*Body); 109 P->setSymbolAndType(Body->getDynamicSymbolTableIndex(), 110 Target->getGotReloc(), IsMips64EL); 111 } else { 112 P->r_offset = RI.r_offset + C.getOutputSectionOff() + Out->getVA(); 113 P->setSymbolAndType(Body->getDynamicSymbolTableIndex(), Type, IsMips64EL); 114 if (IsRela) 115 static_cast<Elf_Rela *>(P)->r_addend = 116 static_cast<const Elf_Rela &>(RI).r_addend; 117 } 118 } 119 } 120 121 template <class ELFT> void RelocationSection<ELFT>::finalize() { 122 this->Header.sh_link = DynSymSec.getSectionIndex(); 123 this->Header.sh_size = Relocs.size() * this->Header.sh_entsize; 124 } 125 126 template <bool Is64Bits> 127 InterpSection<Is64Bits>::InterpSection() 128 : OutputSectionBase<Is64Bits>(".interp", llvm::ELF::SHT_PROGBITS, 129 llvm::ELF::SHF_ALLOC) { 130 this->Header.sh_size = Config->DynamicLinker.size() + 1; 131 this->Header.sh_addralign = 1; 132 } 133 134 template <bool Is64Bits> 135 template <endianness E> 136 void OutputSectionBase<Is64Bits>::writeHeaderTo( 137 typename ELFFile<ELFType<E, Is64Bits>>::Elf_Shdr *SHdr) { 138 SHdr->sh_name = Header.sh_name; 139 SHdr->sh_type = Header.sh_type; 140 SHdr->sh_flags = Header.sh_flags; 141 SHdr->sh_addr = Header.sh_addr; 142 SHdr->sh_offset = Header.sh_offset; 143 SHdr->sh_size = Header.sh_size; 144 SHdr->sh_link = Header.sh_link; 145 SHdr->sh_info = Header.sh_info; 146 SHdr->sh_addralign = Header.sh_addralign; 147 SHdr->sh_entsize = Header.sh_entsize; 148 } 149 150 template <bool Is64Bits> void InterpSection<Is64Bits>::writeTo(uint8_t *Buf) { 151 memcpy(Buf, Config->DynamicLinker.data(), Config->DynamicLinker.size()); 152 } 153 154 template <class ELFT> 155 HashTableSection<ELFT>::HashTableSection(SymbolTableSection<ELFT> &DynSymSec) 156 : OutputSectionBase<ELFT::Is64Bits>(".hash", llvm::ELF::SHT_HASH, 157 llvm::ELF::SHF_ALLOC), 158 DynSymSec(DynSymSec) { 159 this->Header.sh_entsize = sizeof(Elf_Word); 160 this->Header.sh_addralign = sizeof(Elf_Word); 161 } 162 163 template <class ELFT> void HashTableSection<ELFT>::addSymbol(SymbolBody *S) { 164 StringRef Name = S->getName(); 165 DynSymSec.addSymbol(Name); 166 Hashes.push_back(hash(Name)); 167 S->setDynamicSymbolTableIndex(Hashes.size()); 168 } 169 170 template <class ELFT> 171 DynamicSection<ELFT>::DynamicSection(SymbolTable &SymTab, 172 HashTableSection<ELFT> &HashSec, 173 RelocationSection<ELFT> &RelaDynSec) 174 : OutputSectionBase<ELFT::Is64Bits>(".dynamic", llvm::ELF::SHT_DYNAMIC, 175 llvm::ELF::SHF_ALLOC | 176 llvm::ELF::SHF_WRITE), 177 HashSec(HashSec), DynSymSec(HashSec.getDynSymSec()), 178 DynStrSec(DynSymSec.getStrTabSec()), RelaDynSec(RelaDynSec), 179 SymTab(SymTab) { 180 typename Base::HeaderT &Header = this->Header; 181 Header.sh_addralign = ELFT::Is64Bits ? 8 : 4; 182 Header.sh_entsize = ELFT::Is64Bits ? 16 : 8; 183 } 184 185 template <class ELFT> void DynamicSection<ELFT>::finalize() { 186 typename Base::HeaderT &Header = this->Header; 187 Header.sh_link = DynStrSec.getSectionIndex(); 188 189 unsigned NumEntries = 0; 190 if (RelaDynSec.hasRelocs()) { 191 ++NumEntries; // DT_RELA / DT_REL 192 ++NumEntries; // DT_RELASZ / DT_RELSZ 193 ++NumEntries; // DT_RELAENT / DT_RELENT 194 } 195 ++NumEntries; // DT_SYMTAB 196 ++NumEntries; // DT_SYMENT 197 ++NumEntries; // DT_STRTAB 198 ++NumEntries; // DT_STRSZ 199 ++NumEntries; // DT_HASH 200 201 StringRef RPath = Config->RPath; 202 if (!RPath.empty()) { 203 ++NumEntries; // DT_RUNPATH 204 DynStrSec.add(RPath); 205 } 206 207 const std::vector<std::unique_ptr<SharedFileBase>> &SharedFiles = 208 SymTab.getSharedFiles(); 209 for (const std::unique_ptr<SharedFileBase> &File : SharedFiles) 210 DynStrSec.add(File->getName()); 211 NumEntries += SharedFiles.size(); 212 213 ++NumEntries; // DT_NULL 214 215 Header.sh_size = NumEntries * Header.sh_entsize; 216 } 217 218 template <class ELFT> void DynamicSection<ELFT>::writeTo(uint8_t *Buf) { 219 typedef typename std::conditional<ELFT::Is64Bits, Elf64_Dyn, Elf32_Dyn>::type 220 Elf_Dyn; 221 auto *P = reinterpret_cast<Elf_Dyn *>(Buf); 222 223 if (RelaDynSec.hasRelocs()) { 224 bool IsRela = RelaDynSec.isRela(); 225 P->d_tag = IsRela ? DT_RELA : DT_REL; 226 P->d_un.d_ptr = RelaDynSec.getVA(); 227 ++P; 228 229 P->d_tag = IsRela ? DT_RELASZ : DT_RELSZ; 230 P->d_un.d_val = RelaDynSec.getSize(); 231 ++P; 232 233 P->d_tag = IsRela ? DT_RELAENT : DT_RELENT; 234 P->d_un.d_val = IsRela ? sizeof(Elf_Rela) : sizeof(Elf_Rel); 235 ++P; 236 } 237 238 P->d_tag = DT_SYMTAB; 239 P->d_un.d_ptr = DynSymSec.getVA(); 240 ++P; 241 242 P->d_tag = DT_SYMENT; 243 P->d_un.d_ptr = sizeof(Elf_Sym); 244 ++P; 245 246 P->d_tag = DT_STRTAB; 247 P->d_un.d_ptr = DynStrSec.getVA(); 248 ++P; 249 250 P->d_tag = DT_STRSZ; 251 P->d_un.d_val = DynStrSec.data().size(); 252 ++P; 253 254 P->d_tag = DT_HASH; 255 P->d_un.d_ptr = HashSec.getVA(); 256 ++P; 257 258 StringRef RPath = Config->RPath; 259 if (!RPath.empty()) { 260 P->d_tag = DT_RUNPATH; 261 P->d_un.d_val = DynStrSec.getFileOff(RPath); 262 ++P; 263 } 264 265 const std::vector<std::unique_ptr<SharedFileBase>> &SharedFiles = 266 SymTab.getSharedFiles(); 267 for (const std::unique_ptr<SharedFileBase> &File : SharedFiles) { 268 P->d_tag = DT_NEEDED; 269 P->d_un.d_val = DynStrSec.getFileOff(File->getName()); 270 ++P; 271 } 272 273 P->d_tag = DT_NULL; 274 P->d_un.d_val = 0; 275 ++P; 276 } 277 278 template <class ELFT> 279 OutputSection<ELFT>::OutputSection(const PltSection<ELFT> &PltSec, 280 const GotSection<ELFT> &GotSec, 281 const OutputSection<ELFT> &BssSec, 282 StringRef Name, uint32_t sh_type, 283 uintX_t sh_flags) 284 : OutputSectionBase<ELFT::Is64Bits>(Name, sh_type, sh_flags), 285 PltSec(PltSec), GotSec(GotSec), BssSec(BssSec) {} 286 287 template <class ELFT> 288 void OutputSection<ELFT>::addSection(InputSection<ELFT> *C) { 289 Sections.push_back(C); 290 C->setOutputSection(this); 291 uint32_t Align = C->getAlign(); 292 if (Align > this->Header.sh_addralign) 293 this->Header.sh_addralign = Align; 294 295 uintX_t Off = this->Header.sh_size; 296 Off = RoundUpToAlignment(Off, Align); 297 C->setOutputSectionOff(Off); 298 Off += C->getSize(); 299 this->Header.sh_size = Off; 300 } 301 302 template <class ELFT> 303 typename ELFFile<ELFT>::uintX_t 304 lld::elf2::getSymVA(const ELFSymbolBody<ELFT> &S, 305 const OutputSection<ELFT> &BssSec) { 306 switch (S.kind()) { 307 case SymbolBody::DefinedSyntheticKind: 308 return cast<DefinedSynthetic<ELFT>>(S).Section.getVA() + S.Sym.st_value; 309 case SymbolBody::DefinedAbsoluteKind: 310 return S.Sym.st_value; 311 case SymbolBody::DefinedRegularKind: { 312 const auto &DR = cast<DefinedRegular<ELFT>>(S); 313 const InputSection<ELFT> *SC = &DR.Section; 314 OutputSection<ELFT> *OS = SC->getOutputSection(); 315 return OS->getVA() + SC->getOutputSectionOff() + DR.Sym.st_value; 316 } 317 case SymbolBody::DefinedCommonKind: 318 return BssSec.getVA() + cast<DefinedCommon<ELFT>>(S).OffsetInBSS; 319 case SymbolBody::SharedKind: 320 case SymbolBody::UndefinedKind: 321 return 0; 322 case SymbolBody::LazyKind: 323 break; 324 } 325 llvm_unreachable("Lazy symbol reached writer"); 326 } 327 328 template <class ELFT> 329 typename ELFFile<ELFT>::uintX_t 330 lld::elf2::getLocalSymVA(const typename ELFFile<ELFT>::Elf_Sym *Sym, 331 const ObjectFile<ELFT> &File) { 332 uint32_t SecIndex = Sym->st_shndx; 333 334 if (SecIndex == SHN_XINDEX) 335 SecIndex = File.getObj().getExtendedSymbolTableIndex( 336 Sym, File.getSymbolTable(), File.getSymbolTableShndx()); 337 ArrayRef<InputSection<ELFT> *> Sections = File.getSections(); 338 InputSection<ELFT> *Section = Sections[SecIndex]; 339 OutputSection<ELFT> *Out = Section->getOutputSection(); 340 return Out->getVA() + Section->getOutputSectionOff() + Sym->st_value; 341 } 342 343 template <class ELFT> void OutputSection<ELFT>::writeTo(uint8_t *Buf) { 344 for (InputSection<ELFT> *C : Sections) 345 C->writeTo(Buf, BssSec, PltSec, GotSec); 346 } 347 348 template <bool Is64Bits> 349 StringTableSection<Is64Bits>::StringTableSection(bool Dynamic) 350 : OutputSectionBase<Is64Bits>(Dynamic ? ".dynstr" : ".strtab", 351 llvm::ELF::SHT_STRTAB, 352 Dynamic ? (uintX_t)llvm::ELF::SHF_ALLOC : 0), 353 Dynamic(Dynamic) { 354 this->Header.sh_addralign = 1; 355 } 356 357 template <bool Is64Bits> 358 void StringTableSection<Is64Bits>::writeTo(uint8_t *Buf) { 359 StringRef Data = StrTabBuilder.data(); 360 memcpy(Buf, Data.data(), Data.size()); 361 } 362 363 bool lld::elf2::includeInSymtab(const SymbolBody &B) { 364 if (B.isLazy()) 365 return false; 366 if (!B.isUsedInRegularObj()) 367 return false; 368 uint8_t V = B.getMostConstrainingVisibility(); 369 if (V != STV_DEFAULT && V != STV_PROTECTED) 370 return false; 371 return true; 372 } 373 374 bool lld::elf2::includeInDynamicSymtab(const SymbolBody &B) { 375 if (Config->ExportDynamic || Config->Shared) 376 return true; 377 return B.isUsedInDynamicReloc(); 378 } 379 380 bool lld::elf2::shouldKeepInSymtab(StringRef SymName) { 381 if (Config->DiscardNone) 382 return true; 383 384 // ELF defines dynamic locals as symbols which name starts with ".L". 385 return !(Config->DiscardLocals && SymName.startswith(".L")); 386 } 387 388 template <class ELFT> 389 SymbolTableSection<ELFT>::SymbolTableSection( 390 SymbolTable &Table, StringTableSection<ELFT::Is64Bits> &StrTabSec, 391 const OutputSection<ELFT> &BssSec) 392 : OutputSectionBase<ELFT::Is64Bits>( 393 StrTabSec.isDynamic() ? ".dynsym" : ".symtab", 394 StrTabSec.isDynamic() ? llvm::ELF::SHT_DYNSYM : llvm::ELF::SHT_SYMTAB, 395 StrTabSec.isDynamic() ? (uintX_t)llvm::ELF::SHF_ALLOC : 0), 396 Table(Table), StrTabSec(StrTabSec), BssSec(BssSec) { 397 typedef OutputSectionBase<ELFT::Is64Bits> Base; 398 typename Base::HeaderT &Header = this->Header; 399 400 Header.sh_entsize = sizeof(Elf_Sym); 401 Header.sh_addralign = ELFT::Is64Bits ? 8 : 4; 402 } 403 404 template <class ELFT> void SymbolTableSection<ELFT>::writeTo(uint8_t *Buf) { 405 Buf += sizeof(Elf_Sym); 406 407 // All symbols with STB_LOCAL binding precede the weak and global symbols. 408 // .dynsym only contains global symbols. 409 if (!Config->DiscardAll && !StrTabSec.isDynamic()) 410 writeLocalSymbols(Buf); 411 412 writeGlobalSymbols(Buf); 413 } 414 415 template <class ELFT> 416 void SymbolTableSection<ELFT>::writeLocalSymbols(uint8_t *&Buf) { 417 // Iterate over all input object files to copy their local symbols 418 // to the output symbol table pointed by Buf. 419 for (const std::unique_ptr<ObjectFileBase> &FileB : Table.getObjectFiles()) { 420 auto &File = cast<ObjectFile<ELFT>>(*FileB); 421 Elf_Sym_Range Syms = File.getLocalSymbols(); 422 for (const Elf_Sym &Sym : Syms) { 423 ErrorOr<StringRef> SymName = Sym.getName(File.getStringTable()); 424 if (SymName && !shouldKeepInSymtab(*SymName)) 425 continue; 426 auto *ESym = reinterpret_cast<Elf_Sym *>(Buf); 427 Buf += sizeof(*ESym); 428 ESym->st_name = (SymName) ? StrTabSec.getFileOff(*SymName) : 0; 429 ESym->st_size = Sym.st_size; 430 ESym->setBindingAndType(Sym.getBinding(), Sym.getType()); 431 uint32_t SecIndex = Sym.st_shndx; 432 uintX_t VA = Sym.st_value; 433 if (SecIndex == SHN_ABS) { 434 ESym->st_shndx = SHN_ABS; 435 } else { 436 if (SecIndex == SHN_XINDEX) 437 SecIndex = File.getObj().getExtendedSymbolTableIndex( 438 &Sym, File.getSymbolTable(), File.getSymbolTableShndx()); 439 ArrayRef<InputSection<ELFT> *> Sections = File.getSections(); 440 const InputSection<ELFT> *Section = Sections[SecIndex]; 441 const OutputSection<ELFT> *Out = Section->getOutputSection(); 442 ESym->st_shndx = Out->getSectionIndex(); 443 VA += Out->getVA() + Section->getOutputSectionOff(); 444 } 445 ESym->st_value = VA; 446 } 447 } 448 } 449 450 template <class ELFT> 451 void SymbolTableSection<ELFT>::writeGlobalSymbols(uint8_t *&Buf) { 452 // Write the internal symbol table contents to the output symbol table 453 // pointed by Buf. 454 for (const std::pair<StringRef, Symbol *> &P : Table.getSymbols()) { 455 StringRef Name = P.first; 456 Symbol *Sym = P.second; 457 SymbolBody *Body = Sym->Body; 458 if (!includeInSymtab(*Body)) 459 continue; 460 if (StrTabSec.isDynamic() && !includeInDynamicSymtab(*Body)) 461 continue; 462 463 const auto &EBody = *cast<ELFSymbolBody<ELFT>>(Body); 464 const Elf_Sym &InputSym = EBody.Sym; 465 auto *ESym = reinterpret_cast<Elf_Sym *>(Buf); 466 Buf += sizeof(*ESym); 467 ESym->st_name = StrTabSec.getFileOff(Name); 468 469 const OutputSection<ELFT> *Out = nullptr; 470 const InputSection<ELFT> *Section = nullptr; 471 472 switch (EBody.kind()) { 473 case SymbolBody::DefinedSyntheticKind: 474 Out = &cast<DefinedSynthetic<ELFT>>(Body)->Section; 475 break; 476 case SymbolBody::DefinedRegularKind: 477 Section = &cast<DefinedRegular<ELFT>>(EBody).Section; 478 break; 479 case SymbolBody::DefinedCommonKind: 480 Out = &BssSec; 481 break; 482 case SymbolBody::UndefinedKind: 483 case SymbolBody::DefinedAbsoluteKind: 484 case SymbolBody::SharedKind: 485 break; 486 case SymbolBody::LazyKind: 487 llvm_unreachable("Lazy symbol got to output symbol table!"); 488 } 489 490 ESym->setBindingAndType(InputSym.getBinding(), InputSym.getType()); 491 ESym->st_size = InputSym.st_size; 492 ESym->setVisibility(EBody.getMostConstrainingVisibility()); 493 if (InputSym.isAbsolute()) { 494 ESym->st_shndx = SHN_ABS; 495 ESym->st_value = InputSym.st_value; 496 } 497 498 if (Section) 499 Out = Section->getOutputSection(); 500 501 ESym->st_value = getSymVA(EBody, BssSec); 502 503 if (Out) 504 ESym->st_shndx = Out->getSectionIndex(); 505 } 506 } 507 508 namespace lld { 509 namespace elf2 { 510 template class OutputSectionBase<false>; 511 template class OutputSectionBase<true>; 512 513 template void OutputSectionBase<false>::writeHeaderTo<support::little>( 514 ELFFile<ELFType<support::little, false>>::Elf_Shdr *SHdr); 515 template void OutputSectionBase<true>::writeHeaderTo<support::little>( 516 ELFFile<ELFType<support::little, true>>::Elf_Shdr *SHdr); 517 template void OutputSectionBase<false>::writeHeaderTo<support::big>( 518 ELFFile<ELFType<support::big, false>>::Elf_Shdr *SHdr); 519 template void OutputSectionBase<true>::writeHeaderTo<support::big>( 520 ELFFile<ELFType<support::big, true>>::Elf_Shdr *SHdr); 521 522 template class GotSection<ELF32LE>; 523 template class GotSection<ELF32BE>; 524 template class GotSection<ELF64LE>; 525 template class GotSection<ELF64BE>; 526 527 template class PltSection<ELF32LE>; 528 template class PltSection<ELF32BE>; 529 template class PltSection<ELF64LE>; 530 template class PltSection<ELF64BE>; 531 532 template class RelocationSection<ELF32LE>; 533 template class RelocationSection<ELF32BE>; 534 template class RelocationSection<ELF64LE>; 535 template class RelocationSection<ELF64BE>; 536 537 template class InterpSection<false>; 538 template class InterpSection<true>; 539 540 template class HashTableSection<ELF32LE>; 541 template class HashTableSection<ELF32BE>; 542 template class HashTableSection<ELF64LE>; 543 template class HashTableSection<ELF64BE>; 544 545 template class DynamicSection<ELF32LE>; 546 template class DynamicSection<ELF32BE>; 547 template class DynamicSection<ELF64LE>; 548 template class DynamicSection<ELF64BE>; 549 550 template class OutputSection<ELF32LE>; 551 template class OutputSection<ELF32BE>; 552 template class OutputSection<ELF64LE>; 553 template class OutputSection<ELF64BE>; 554 555 template class StringTableSection<false>; 556 template class StringTableSection<true>; 557 558 template class SymbolTableSection<ELF32LE>; 559 template class SymbolTableSection<ELF32BE>; 560 template class SymbolTableSection<ELF64LE>; 561 template class SymbolTableSection<ELF64BE>; 562 563 template ELFFile<ELF32LE>::uintX_t 564 getSymVA(const ELFSymbolBody<ELF32LE> &, const OutputSection<ELF32LE> &); 565 566 template ELFFile<ELF32BE>::uintX_t 567 getSymVA(const ELFSymbolBody<ELF32BE> &, const OutputSection<ELF32BE> &); 568 569 template ELFFile<ELF64LE>::uintX_t 570 getSymVA(const ELFSymbolBody<ELF64LE> &, const OutputSection<ELF64LE> &); 571 572 template ELFFile<ELF64BE>::uintX_t 573 getSymVA(const ELFSymbolBody<ELF64BE> &, const OutputSection<ELF64BE> &); 574 575 template ELFFile<ELF32LE>::uintX_t 576 getLocalSymVA(const ELFFile<ELF32LE>::Elf_Sym *, const ObjectFile<ELF32LE> &); 577 578 template ELFFile<ELF32BE>::uintX_t 579 getLocalSymVA(const ELFFile<ELF32BE>::Elf_Sym *, const ObjectFile<ELF32BE> &); 580 581 template ELFFile<ELF64LE>::uintX_t 582 getLocalSymVA(const ELFFile<ELF64LE>::Elf_Sym *, const ObjectFile<ELF64LE> &); 583 584 template ELFFile<ELF64BE>::uintX_t 585 getLocalSymVA(const ELFFile<ELF64BE>::Elf_Sym *, const ObjectFile<ELF64BE> &); 586 } 587 } 588