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 #include "llvm/Support/MathExtras.h" 15 16 using namespace llvm; 17 using namespace llvm::object; 18 using namespace llvm::support::endian; 19 using namespace llvm::ELF; 20 21 using namespace lld; 22 using namespace lld::elf2; 23 24 template <class ELFT> 25 OutputSectionBase<ELFT>::OutputSectionBase(StringRef Name, uint32_t sh_type, 26 uintX_t sh_flags) 27 : Name(Name) { 28 memset(&Header, 0, sizeof(Elf_Shdr)); 29 Header.sh_type = sh_type; 30 Header.sh_flags = sh_flags; 31 } 32 33 template <class ELFT> 34 GotPltSection<ELFT>::GotPltSection() 35 : OutputSectionBase<ELFT>(".got.plt", llvm::ELF::SHT_PROGBITS, 36 llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_WRITE) { 37 this->Header.sh_addralign = sizeof(uintX_t); 38 // .got.plt has 3 reserved entry 39 Entries.resize(3); 40 } 41 42 template <class ELFT> void GotPltSection<ELFT>::addEntry(SymbolBody *Sym) { 43 Sym->GotPltIndex = Entries.size(); 44 Entries.push_back(Sym); 45 } 46 47 template <class ELFT> bool GotPltSection<ELFT>::empty() const { 48 return Entries.size() == 3; 49 } 50 51 template <class ELFT> 52 typename GotPltSection<ELFT>::uintX_t 53 GotPltSection<ELFT>::getEntryAddr(const SymbolBody &B) const { 54 return this->getVA() + B.GotPltIndex * sizeof(uintX_t); 55 } 56 57 template <class ELFT> void GotPltSection<ELFT>::finalize() { 58 this->Header.sh_size = Entries.size() * sizeof(uintX_t); 59 } 60 61 template <class ELFT> void GotPltSection<ELFT>::writeTo(uint8_t *Buf) { 62 write<uintX_t, ELFT::TargetEndianness, sizeof(uintX_t)>( 63 Buf, Out<ELFT>::Dynamic->getVA()); 64 for (const SymbolBody *B : Entries) { 65 if (B) 66 Target->writeGotPltEntry(Buf, Out<ELFT>::Plt->getEntryAddr(*B)); 67 Buf += sizeof(uintX_t); 68 } 69 } 70 71 template <class ELFT> 72 GotSection<ELFT>::GotSection() 73 : OutputSectionBase<ELFT>(".got", llvm::ELF::SHT_PROGBITS, 74 llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_WRITE) { 75 this->Header.sh_addralign = sizeof(uintX_t); 76 } 77 78 template <class ELFT> void GotSection<ELFT>::addEntry(SymbolBody *Sym) { 79 Sym->GotIndex = Entries.size(); 80 Entries.push_back(Sym); 81 } 82 83 template <class ELFT> 84 typename GotSection<ELFT>::uintX_t 85 GotSection<ELFT>::getEntryAddr(const SymbolBody &B) const { 86 return this->getVA() + B.GotIndex * sizeof(uintX_t); 87 } 88 89 template <class ELFT> void GotSection<ELFT>::writeTo(uint8_t *Buf) { 90 for (const SymbolBody *B : Entries) { 91 uint8_t *Entry = Buf; 92 Buf += sizeof(uintX_t); 93 if (canBePreempted(B, false)) 94 continue; // The dynamic linker will take care of it. 95 uintX_t VA = getSymVA<ELFT>(*B); 96 write<uintX_t, ELFT::TargetEndianness, sizeof(uintX_t)>(Entry, VA); 97 } 98 } 99 100 template <class ELFT> 101 PltSection<ELFT>::PltSection() 102 : OutputSectionBase<ELFT>(".plt", llvm::ELF::SHT_PROGBITS, 103 llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_EXECINSTR) { 104 this->Header.sh_addralign = 16; 105 } 106 107 template <class ELFT> void PltSection<ELFT>::writeTo(uint8_t *Buf) { 108 size_t Off = 0; 109 bool LazyReloc = Target->supportsLazyRelocations(); 110 if (LazyReloc) { 111 // First write PLT[0] entry which is special. 112 Target->writePltZeroEntry(Buf, Out<ELFT>::GotPlt->getVA(), this->getVA()); 113 Off += Target->getPltZeroEntrySize(); 114 } 115 for (const SymbolBody *E : Entries) { 116 uint64_t Got = LazyReloc ? Out<ELFT>::GotPlt->getEntryAddr(*E) 117 : Out<ELFT>::Got->getEntryAddr(*E); 118 uint64_t Plt = this->getVA() + Off; 119 Target->writePltEntry(Buf + Off, Got, Plt, E->PltIndex); 120 Off += Target->getPltEntrySize(); 121 } 122 } 123 124 template <class ELFT> void PltSection<ELFT>::addEntry(SymbolBody *Sym) { 125 Sym->PltIndex = Entries.size(); 126 Entries.push_back(Sym); 127 } 128 129 template <class ELFT> 130 typename PltSection<ELFT>::uintX_t 131 PltSection<ELFT>::getEntryAddr(const SymbolBody &B) const { 132 return this->getVA() + Target->getPltZeroEntrySize() + 133 B.PltIndex * Target->getPltEntrySize(); 134 } 135 136 template <class ELFT> void PltSection<ELFT>::finalize() { 137 this->Header.sh_size = Target->getPltZeroEntrySize() + 138 Entries.size() * Target->getPltEntrySize(); 139 } 140 141 template <class ELFT> 142 RelocationSection<ELFT>::RelocationSection(StringRef Name, bool IsRela) 143 : OutputSectionBase<ELFT>(Name, 144 IsRela ? llvm::ELF::SHT_RELA : llvm::ELF::SHT_REL, 145 llvm::ELF::SHF_ALLOC), 146 IsRela(IsRela) { 147 this->Header.sh_entsize = IsRela ? sizeof(Elf_Rela) : sizeof(Elf_Rel); 148 this->Header.sh_addralign = ELFT::Is64Bits ? 8 : 4; 149 } 150 151 template <class ELFT> void RelocationSection<ELFT>::writeTo(uint8_t *Buf) { 152 const unsigned EntrySize = IsRela ? sizeof(Elf_Rela) : sizeof(Elf_Rel); 153 for (const DynamicReloc<ELFT> &Rel : Relocs) { 154 auto *P = reinterpret_cast<Elf_Rel *>(Buf); 155 Buf += EntrySize; 156 157 const InputSection<ELFT> &C = Rel.C; 158 const Elf_Rel &RI = Rel.RI; 159 uint32_t SymIndex = RI.getSymbol(Config->Mips64EL); 160 const ObjectFile<ELFT> &File = *C.getFile(); 161 SymbolBody *Body = File.getSymbolBody(SymIndex); 162 if (Body) 163 Body = Body->repl(); 164 165 uint32_t Type = RI.getType(Config->Mips64EL); 166 bool NeedsGot = Body && Target->relocNeedsGot(Type, *Body); 167 bool CanBePreempted = canBePreempted(Body, NeedsGot); 168 bool LazyReloc = Body && Target->supportsLazyRelocations() && 169 Target->relocNeedsPlt(Type, *Body); 170 171 if (CanBePreempted) { 172 if (NeedsGot) 173 P->setSymbolAndType(Body->getDynamicSymbolTableIndex(), 174 LazyReloc ? Target->getPltReloc() 175 : Target->getGotReloc(), 176 Config->Mips64EL); 177 else 178 P->setSymbolAndType(Body->getDynamicSymbolTableIndex(), Type, 179 Config->Mips64EL); 180 } else { 181 P->setSymbolAndType(0, Target->getRelativeReloc(), Config->Mips64EL); 182 } 183 184 if (NeedsGot) { 185 if (LazyReloc) 186 P->r_offset = Out<ELFT>::GotPlt->getEntryAddr(*Body); 187 else 188 P->r_offset = Out<ELFT>::Got->getEntryAddr(*Body); 189 } else { 190 P->r_offset = RI.r_offset + C.OutSec->getVA() + C.OutSecOff; 191 } 192 193 uintX_t OrigAddend = 0; 194 if (IsRela && !NeedsGot) 195 OrigAddend = static_cast<const Elf_Rela &>(RI).r_addend; 196 197 uintX_t Addend; 198 if (CanBePreempted) 199 Addend = OrigAddend; 200 else if (Body) 201 Addend = getSymVA<ELFT>(cast<ELFSymbolBody<ELFT>>(*Body)) + OrigAddend; 202 else if (IsRela) 203 Addend = getLocalRelTarget(File, static_cast<const Elf_Rela &>(RI)); 204 else 205 Addend = getLocalRelTarget(File, RI); 206 207 if (IsRela) 208 static_cast<Elf_Rela *>(P)->r_addend = Addend; 209 } 210 } 211 212 template <class ELFT> void RelocationSection<ELFT>::finalize() { 213 this->Header.sh_link = Out<ELFT>::DynSymTab->SectionIndex; 214 this->Header.sh_size = Relocs.size() * this->Header.sh_entsize; 215 } 216 217 template <class ELFT> 218 InterpSection<ELFT>::InterpSection() 219 : OutputSectionBase<ELFT>(".interp", llvm::ELF::SHT_PROGBITS, 220 llvm::ELF::SHF_ALLOC) { 221 this->Header.sh_size = Config->DynamicLinker.size() + 1; 222 this->Header.sh_addralign = 1; 223 } 224 225 template <class ELFT> 226 void OutputSectionBase<ELFT>::writeHeaderTo(Elf_Shdr *SHdr) { 227 *SHdr = Header; 228 } 229 230 template <class ELFT> void InterpSection<ELFT>::writeTo(uint8_t *Buf) { 231 memcpy(Buf, Config->DynamicLinker.data(), Config->DynamicLinker.size()); 232 } 233 234 template <class ELFT> 235 HashTableSection<ELFT>::HashTableSection() 236 : OutputSectionBase<ELFT>(".hash", llvm::ELF::SHT_HASH, 237 llvm::ELF::SHF_ALLOC) { 238 this->Header.sh_entsize = sizeof(Elf_Word); 239 this->Header.sh_addralign = sizeof(Elf_Word); 240 } 241 242 static uint32_t hashSysv(StringRef Name) { 243 uint32_t H = 0; 244 for (char C : Name) { 245 H = (H << 4) + C; 246 uint32_t G = H & 0xf0000000; 247 if (G) 248 H ^= G >> 24; 249 H &= ~G; 250 } 251 return H; 252 } 253 254 template <class ELFT> void HashTableSection<ELFT>::finalize() { 255 this->Header.sh_link = Out<ELFT>::DynSymTab->SectionIndex; 256 257 unsigned NumEntries = 2; // nbucket and nchain. 258 NumEntries += Out<ELFT>::DynSymTab->getNumSymbols(); // The chain entries. 259 260 // Create as many buckets as there are symbols. 261 // FIXME: This is simplistic. We can try to optimize it, but implementing 262 // support for SHT_GNU_HASH is probably even more profitable. 263 NumEntries += Out<ELFT>::DynSymTab->getNumSymbols(); 264 this->Header.sh_size = NumEntries * sizeof(Elf_Word); 265 } 266 267 template <class ELFT> void HashTableSection<ELFT>::writeTo(uint8_t *Buf) { 268 unsigned NumSymbols = Out<ELFT>::DynSymTab->getNumSymbols(); 269 auto *P = reinterpret_cast<Elf_Word *>(Buf); 270 *P++ = NumSymbols; // nbucket 271 *P++ = NumSymbols; // nchain 272 273 Elf_Word *Buckets = P; 274 Elf_Word *Chains = P + NumSymbols; 275 276 for (const typename SymbolTableSection<ELFT>::SymbolData &Item : 277 Out<ELFT>::DynSymTab->getSymbols()) { 278 SymbolBody *Body = Item.Body; 279 StringRef Name = Body->getName(); 280 unsigned I = Body->getDynamicSymbolTableIndex(); 281 uint32_t Hash = hashSysv(Name) % NumSymbols; 282 Chains[I] = Buckets[Hash]; 283 Buckets[Hash] = I; 284 } 285 } 286 287 static uint32_t hashGnu(StringRef Name) { 288 uint32_t H = 5381; 289 for (uint8_t C : Name) 290 H = (H << 5) + H + C; 291 return H; 292 } 293 294 template <class ELFT> 295 GnuHashTableSection<ELFT>::GnuHashTableSection() 296 : OutputSectionBase<ELFT>(".gnu.hash", llvm::ELF::SHT_GNU_HASH, 297 llvm::ELF::SHF_ALLOC) { 298 this->Header.sh_entsize = ELFT::Is64Bits ? 0 : 4; 299 this->Header.sh_addralign = ELFT::Is64Bits ? 8 : 4; 300 } 301 302 template <class ELFT> 303 unsigned GnuHashTableSection<ELFT>::calcNBuckets(unsigned NumHashed) { 304 if (!NumHashed) 305 return 0; 306 307 // These values are prime numbers which are not greater than 2^(N-1) + 1. 308 // In result, for any particular NumHashed we return a prime number 309 // which is not greater than NumHashed. 310 static const unsigned Primes[] = { 311 1, 1, 3, 3, 7, 13, 31, 61, 127, 251, 312 509, 1021, 2039, 4093, 8191, 16381, 32749, 65521, 131071}; 313 314 return Primes[std::min<unsigned>(Log2_32_Ceil(NumHashed), 315 array_lengthof(Primes) - 1)]; 316 } 317 318 // Bloom filter estimation: at least 8 bits for each hashed symbol. 319 // GNU Hash table requirement: it should be a power of 2, 320 // the minimum value is 1, even for an empty table. 321 // Expected results for a 32-bit target: 322 // calcMaskWords(0..4) = 1 323 // calcMaskWords(5..8) = 2 324 // calcMaskWords(9..16) = 4 325 // For a 64-bit target: 326 // calcMaskWords(0..8) = 1 327 // calcMaskWords(9..16) = 2 328 // calcMaskWords(17..32) = 4 329 template <class ELFT> 330 unsigned GnuHashTableSection<ELFT>::calcMaskWords(unsigned NumHashed) { 331 if (!NumHashed) 332 return 1; 333 return NextPowerOf2((NumHashed - 1) / sizeof(Elf_Off)); 334 } 335 336 template <class ELFT> void GnuHashTableSection<ELFT>::finalize() { 337 const unsigned NumHashed = Out<ELFT>::DynSymTab->getNumGnuHashSymbols(); 338 NBuckets = calcNBuckets(NumHashed); 339 MaskWords = calcMaskWords(NumHashed); 340 // Second hash shift estimation: just predefined values. 341 Shift2 = ELFT::Is64Bits ? 6 : 5; 342 343 this->Header.sh_link = Out<ELFT>::DynSymTab->SectionIndex; 344 this->Header.sh_size = sizeof(Elf_Word) * 4 // Header 345 + sizeof(Elf_Off) * MaskWords // Bloom Filter 346 + sizeof(Elf_Word) * NBuckets // Hash Buckets 347 + sizeof(Elf_Word) * NumHashed; // Hash Values 348 } 349 350 template <class ELFT> void GnuHashTableSection<ELFT>::writeTo(uint8_t *Buf) { 351 writeHeader(Buf); 352 if (!NBuckets) // There are no hashed symbols 353 return; 354 writeBloomFilter(Buf); 355 writeHashTable(Buf); 356 } 357 358 template <class ELFT> 359 void GnuHashTableSection<ELFT>::writeHeader(uint8_t *&Buf) { 360 auto *P = reinterpret_cast<Elf_Word *>(Buf); 361 *P++ = NBuckets; 362 *P++ = Out<ELFT>::DynSymTab->getNumSymbols() - 363 Out<ELFT>::DynSymTab->getNumGnuHashSymbols(); 364 *P++ = MaskWords; 365 *P++ = Shift2; 366 Buf = reinterpret_cast<uint8_t *>(P); 367 } 368 369 template <class ELFT> 370 void GnuHashTableSection<ELFT>::writeBloomFilter(uint8_t *&Buf) { 371 unsigned C = sizeof(Elf_Off) * 8; 372 373 auto *Masks = reinterpret_cast<Elf_Off *>(Buf); 374 for (const typename SymbolTableSection<ELFT>::SymbolData &Item : 375 Out<ELFT>::DynSymTab->getGnuHashSymbols()) { 376 size_t Pos = (Item.GnuHash / C) & (MaskWords - 1); 377 uintX_t V = (uintX_t(1) << (Item.GnuHash % C)) | 378 (uintX_t(1) << ((Item.GnuHash >> Shift2) % C)); 379 Masks[Pos] |= V; 380 } 381 Buf += sizeof(Elf_Off) * MaskWords; 382 } 383 384 template <class ELFT> 385 void GnuHashTableSection<ELFT>::writeHashTable(uint8_t *Buf) { 386 Elf_Word *Buckets = reinterpret_cast<Elf_Word *>(Buf); 387 Elf_Word *Values = Buckets + NBuckets; 388 389 int PrevBucket = -1; 390 int I = 0; 391 for (const typename SymbolTableSection<ELFT>::SymbolData &Item : 392 Out<ELFT>::DynSymTab->getGnuHashSymbols()) { 393 int Bucket = Item.GnuHash % NBuckets; 394 assert(PrevBucket <= Bucket); 395 if (Bucket != PrevBucket) { 396 Buckets[Bucket] = Item.Body->getDynamicSymbolTableIndex(); 397 PrevBucket = Bucket; 398 if (I > 0) 399 Values[I - 1] |= 1; 400 } 401 Values[I] = Item.GnuHash & ~1; 402 ++I; 403 } 404 if (I > 0) 405 Values[I - 1] |= 1; 406 } 407 408 template <class ELFT> 409 DynamicSection<ELFT>::DynamicSection(SymbolTable<ELFT> &SymTab) 410 : OutputSectionBase<ELFT>(".dynamic", llvm::ELF::SHT_DYNAMIC, 411 llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_WRITE), 412 SymTab(SymTab) { 413 Elf_Shdr &Header = this->Header; 414 Header.sh_addralign = ELFT::Is64Bits ? 8 : 4; 415 Header.sh_entsize = ELFT::Is64Bits ? 16 : 8; 416 } 417 418 template <class ELFT> void DynamicSection<ELFT>::finalize() { 419 if (this->Header.sh_size) 420 return; // Already finalized. 421 422 Elf_Shdr &Header = this->Header; 423 Header.sh_link = Out<ELFT>::DynStrTab->SectionIndex; 424 425 unsigned NumEntries = 0; 426 if (Out<ELFT>::RelaDyn->hasRelocs()) { 427 ++NumEntries; // DT_RELA / DT_REL 428 ++NumEntries; // DT_RELASZ / DT_RELSZ 429 ++NumEntries; // DT_RELAENT / DT_RELENT 430 } 431 if (Out<ELFT>::RelaPlt && Out<ELFT>::RelaPlt->hasRelocs()) { 432 ++NumEntries; // DT_JMPREL 433 ++NumEntries; // DT_PLTRELSZ 434 ++NumEntries; // DT_PLTGOT 435 ++NumEntries; // DT_PLTREL 436 } 437 438 ++NumEntries; // DT_SYMTAB 439 ++NumEntries; // DT_SYMENT 440 ++NumEntries; // DT_STRTAB 441 ++NumEntries; // DT_STRSZ 442 if (Out<ELFT>::GnuHashTab) 443 ++NumEntries; // DT_GNU_HASH 444 if (Out<ELFT>::HashTab) 445 ++NumEntries; // DT_HASH 446 447 if (!Config->RPath.empty()) { 448 ++NumEntries; // DT_RUNPATH / DT_RPATH 449 Out<ELFT>::DynStrTab->add(Config->RPath); 450 } 451 452 if (!Config->SoName.empty()) { 453 ++NumEntries; // DT_SONAME 454 Out<ELFT>::DynStrTab->add(Config->SoName); 455 } 456 457 if (PreInitArraySec) 458 NumEntries += 2; 459 if (InitArraySec) 460 NumEntries += 2; 461 if (FiniArraySec) 462 NumEntries += 2; 463 464 for (const std::unique_ptr<SharedFile<ELFT>> &F : SymTab.getSharedFiles()) { 465 if (!F->isNeeded()) 466 continue; 467 Out<ELFT>::DynStrTab->add(F->getSoName()); 468 ++NumEntries; 469 } 470 471 if (Symbol *S = SymTab.getSymbols().lookup(Config->Init)) 472 InitSym = dyn_cast<ELFSymbolBody<ELFT>>(S->Body); 473 if (Symbol *S = SymTab.getSymbols().lookup(Config->Fini)) 474 FiniSym = dyn_cast<ELFSymbolBody<ELFT>>(S->Body); 475 if (InitSym) 476 ++NumEntries; // DT_INIT 477 if (FiniSym) 478 ++NumEntries; // DT_FINI 479 480 if (Config->Bsymbolic) 481 DtFlags |= DF_SYMBOLIC; 482 if (Config->ZNodelete) 483 DtFlags1 |= DF_1_NODELETE; 484 if (Config->ZNow) { 485 DtFlags |= DF_BIND_NOW; 486 DtFlags1 |= DF_1_NOW; 487 } 488 if (Config->ZOrigin) { 489 DtFlags |= DF_ORIGIN; 490 DtFlags1 |= DF_1_ORIGIN; 491 } 492 493 if (DtFlags) 494 ++NumEntries; // DT_FLAGS 495 if (DtFlags1) 496 ++NumEntries; // DT_FLAGS_1 497 ++NumEntries; // DT_NULL 498 499 Header.sh_size = NumEntries * Header.sh_entsize; 500 } 501 502 template <class ELFT> void DynamicSection<ELFT>::writeTo(uint8_t *Buf) { 503 auto *P = reinterpret_cast<Elf_Dyn *>(Buf); 504 505 auto WritePtr = [&](int32_t Tag, uint64_t Val) { 506 P->d_tag = Tag; 507 P->d_un.d_ptr = Val; 508 ++P; 509 }; 510 511 auto WriteVal = [&](int32_t Tag, uint32_t Val) { 512 P->d_tag = Tag; 513 P->d_un.d_val = Val; 514 ++P; 515 }; 516 517 if (Out<ELFT>::RelaDyn->hasRelocs()) { 518 bool IsRela = Out<ELFT>::RelaDyn->isRela(); 519 WritePtr(IsRela ? DT_RELA : DT_REL, Out<ELFT>::RelaDyn->getVA()); 520 WriteVal(IsRela ? DT_RELASZ : DT_RELSZ, Out<ELFT>::RelaDyn->getSize()); 521 WriteVal(IsRela ? DT_RELAENT : DT_RELENT, 522 IsRela ? sizeof(Elf_Rela) : sizeof(Elf_Rel)); 523 } 524 if (Out<ELFT>::RelaPlt && Out<ELFT>::RelaPlt->hasRelocs()) { 525 WritePtr(DT_JMPREL, Out<ELFT>::RelaPlt->getVA()); 526 WriteVal(DT_PLTRELSZ, Out<ELFT>::RelaPlt->getSize()); 527 WritePtr(DT_PLTGOT, Out<ELFT>::GotPlt->getVA()); 528 WriteVal(DT_PLTREL, Out<ELFT>::RelaPlt->isRela() ? DT_RELA : DT_REL); 529 } 530 531 WritePtr(DT_SYMTAB, Out<ELFT>::DynSymTab->getVA()); 532 WritePtr(DT_SYMENT, sizeof(Elf_Sym)); 533 WritePtr(DT_STRTAB, Out<ELFT>::DynStrTab->getVA()); 534 WriteVal(DT_STRSZ, Out<ELFT>::DynStrTab->data().size()); 535 if (Out<ELFT>::GnuHashTab) 536 WritePtr(DT_GNU_HASH, Out<ELFT>::GnuHashTab->getVA()); 537 if (Out<ELFT>::HashTab) 538 WritePtr(DT_HASH, Out<ELFT>::HashTab->getVA()); 539 540 if (!Config->RPath.empty()) 541 542 // If --enable-new-dtags is set lld emits DT_RUNPATH 543 // instead of DT_RPATH. The two tags are functionally 544 // equivalent except for the following: 545 // - DT_RUNPATH is searched after LD_LIBRARY_PATH, while 546 // DT_RPATH is searched before. 547 // - DT_RUNPATH is used only to search for direct 548 // dependencies of the object it's contained in, while 549 // DT_RPATH is used for indirect dependencies as well. 550 WriteVal(Config->EnableNewDtags ? DT_RUNPATH : DT_RPATH, 551 Out<ELFT>::DynStrTab->getFileOff(Config->RPath)); 552 553 if (!Config->SoName.empty()) 554 WriteVal(DT_SONAME, Out<ELFT>::DynStrTab->getFileOff(Config->SoName)); 555 556 auto WriteArray = [&](int32_t T1, int32_t T2, 557 const OutputSectionBase<ELFT> *Sec) { 558 if (!Sec) 559 return; 560 WritePtr(T1, Sec->getVA()); 561 WriteVal(T2, Sec->getSize()); 562 }; 563 WriteArray(DT_PREINIT_ARRAY, DT_PREINIT_ARRAYSZ, PreInitArraySec); 564 WriteArray(DT_INIT_ARRAY, DT_INIT_ARRAYSZ, InitArraySec); 565 WriteArray(DT_FINI_ARRAY, DT_FINI_ARRAYSZ, FiniArraySec); 566 567 for (const std::unique_ptr<SharedFile<ELFT>> &F : SymTab.getSharedFiles()) 568 if (F->isNeeded()) 569 WriteVal(DT_NEEDED, Out<ELFT>::DynStrTab->getFileOff(F->getSoName())); 570 571 if (InitSym) 572 WritePtr(DT_INIT, getSymVA<ELFT>(*InitSym)); 573 if (FiniSym) 574 WritePtr(DT_FINI, getSymVA<ELFT>(*FiniSym)); 575 if (DtFlags) 576 WriteVal(DT_FLAGS, DtFlags); 577 if (DtFlags1) 578 WriteVal(DT_FLAGS_1, DtFlags1); 579 WriteVal(DT_NULL, 0); 580 } 581 582 template <class ELFT> 583 OutputSection<ELFT>::OutputSection(StringRef Name, uint32_t sh_type, 584 uintX_t sh_flags) 585 : OutputSectionBase<ELFT>(Name, sh_type, sh_flags) {} 586 587 template <class ELFT> 588 void OutputSection<ELFT>::addSection(InputSection<ELFT> *C) { 589 Sections.push_back(C); 590 C->OutSec = this; 591 uint32_t Align = C->getAlign(); 592 if (Align > this->Header.sh_addralign) 593 this->Header.sh_addralign = Align; 594 595 uintX_t Off = this->Header.sh_size; 596 Off = RoundUpToAlignment(Off, Align); 597 C->OutSecOff = Off; 598 Off += C->getSize(); 599 this->Header.sh_size = Off; 600 } 601 602 template <class ELFT> 603 typename ELFFile<ELFT>::uintX_t lld::elf2::getSymVA(const SymbolBody &S) { 604 switch (S.kind()) { 605 case SymbolBody::DefinedSyntheticKind: { 606 auto &D = cast<DefinedSynthetic<ELFT>>(S); 607 return D.Section.getVA() + D.Sym.st_value; 608 } 609 case SymbolBody::DefinedAbsoluteKind: 610 return cast<DefinedAbsolute<ELFT>>(S).Sym.st_value; 611 case SymbolBody::DefinedRegularKind: { 612 const auto &DR = cast<DefinedRegular<ELFT>>(S); 613 const InputSectionBase<ELFT> &SC = DR.Section; 614 return SC.OutSec->getVA() + SC.getOffset(DR.Sym); 615 } 616 case SymbolBody::DefinedCommonKind: 617 return Out<ELFT>::Bss->getVA() + cast<DefinedCommon<ELFT>>(S).OffsetInBSS; 618 case SymbolBody::SharedKind: 619 case SymbolBody::UndefinedKind: 620 return 0; 621 case SymbolBody::LazyKind: 622 assert(S.isUsedInRegularObj() && "Lazy symbol reached writer"); 623 return 0; 624 } 625 llvm_unreachable("Invalid symbol kind"); 626 } 627 628 // Returns a VA which a relocatin RI refers to. Used only for local symbols. 629 // For non-local symbols, use getSymVA instead. 630 template <class ELFT, bool IsRela> 631 typename ELFFile<ELFT>::uintX_t 632 lld::elf2::getLocalRelTarget(const ObjectFile<ELFT> &File, 633 const Elf_Rel_Impl<ELFT, IsRela> &RI) { 634 typedef typename ELFFile<ELFT>::Elf_Sym Elf_Sym; 635 typedef typename ELFFile<ELFT>::uintX_t uintX_t; 636 637 uintX_t Addend = getAddend<ELFT>(RI); 638 639 // PPC64 has a special relocation representing the TOC base pointer 640 // that does not have a corresponding symbol. 641 if (Config->EMachine == EM_PPC64 && RI.getType(false) == R_PPC64_TOC) 642 return getPPC64TocBase() + Addend; 643 644 const Elf_Sym *Sym = 645 File.getObj().getRelocationSymbol(&RI, File.getSymbolTable()); 646 647 if (!Sym) 648 error("Unsupported relocation without symbol"); 649 650 // According to the ELF spec reference to a local symbol from outside 651 // the group are not allowed. Unfortunately .eh_frame breaks that rule 652 // and must be treated specially. For now we just replace the symbol with 653 // 0. 654 InputSectionBase<ELFT> *Section = File.getSection(*Sym); 655 if (Section == &InputSection<ELFT>::Discarded) 656 return Addend; 657 658 uintX_t VA = Section->OutSec->getVA(); 659 if (isa<InputSection<ELFT>>(Section)) 660 return VA + Section->getOffset(*Sym) + Addend; 661 662 uintX_t Offset = Sym->st_value; 663 if (Sym->getType() == STT_SECTION) { 664 Offset += Addend; 665 Addend = 0; 666 } 667 return VA + cast<MergeInputSection<ELFT>>(Section)->getOffset(Offset) + 668 Addend; 669 } 670 671 // Returns true if a symbol can be replaced at load-time by a symbol 672 // with the same name defined in other ELF executable or DSO. 673 bool lld::elf2::canBePreempted(const SymbolBody *Body, bool NeedsGot) { 674 if (!Body) 675 return false; // Body is a local symbol. 676 if (Body->isShared()) 677 return true; 678 679 if (Body->isUndefined()) { 680 if (!Body->isWeak()) 681 return true; 682 683 // This is an horrible corner case. Ideally we would like to say that any 684 // undefined symbol can be preempted so that the dynamic linker has a 685 // chance of finding it at runtime. 686 // 687 // The problem is that the code sequence used to test for weak undef 688 // functions looks like 689 // if (func) func() 690 // If the code is -fPIC the first reference is a load from the got and 691 // everything works. 692 // If the code is not -fPIC there is no reasonable way to solve it: 693 // * A relocation writing to the text segment will fail (it is ro). 694 // * A copy relocation doesn't work for functions. 695 // * The trick of using a plt entry as the address would fail here since 696 // the plt entry would have a non zero address. 697 // Since we cannot do anything better, we just resolve the symbol to 0 and 698 // don't produce a dynamic relocation. 699 // 700 // As an extra hack, assume that if we are producing a shared library the 701 // user knows what he or she is doing and can handle a dynamic relocation. 702 return Config->Shared || NeedsGot; 703 } 704 if (!Config->Shared) 705 return false; 706 return Body->getVisibility() == STV_DEFAULT; 707 } 708 709 template <class ELFT> void OutputSection<ELFT>::writeTo(uint8_t *Buf) { 710 for (InputSection<ELFT> *C : Sections) 711 C->writeTo(Buf); 712 } 713 714 template <class ELFT> 715 MergeOutputSection<ELFT>::MergeOutputSection(StringRef Name, uint32_t sh_type, 716 uintX_t sh_flags) 717 : OutputSectionBase<ELFT>(Name, sh_type, sh_flags) {} 718 719 template <class ELFT> void MergeOutputSection<ELFT>::writeTo(uint8_t *Buf) { 720 for (const std::pair<ArrayRef<uint8_t>, uintX_t> &P : Offsets) { 721 ArrayRef<uint8_t> Data = P.first; 722 memcpy(Buf, Data.data(), Data.size()); 723 Buf += Data.size(); 724 } 725 } 726 727 template <class ELFT> 728 void MergeOutputSection<ELFT>::addSection(MergeInputSection<ELFT> *S) { 729 S->OutSec = this; 730 uint32_t Align = S->getAlign(); 731 if (Align > this->Header.sh_addralign) 732 this->Header.sh_addralign = Align; 733 734 uintX_t Off = this->Header.sh_size; 735 ArrayRef<uint8_t> Data = S->getSectionData(); 736 uintX_t EntSize = S->getSectionHdr()->sh_entsize; 737 if (Data.size() % EntSize) 738 error("SHF_MERGE section size must be a multiple of sh_entsize"); 739 for (unsigned I = 0, N = Data.size(); I != N; I += EntSize) { 740 auto P = Offsets.insert(std::make_pair(Data.slice(I, EntSize), Off)); 741 if (P.second) 742 Off += EntSize; 743 } 744 this->Header.sh_size = Off; 745 } 746 747 template <class ELFT> 748 unsigned MergeOutputSection<ELFT>::getOffset(ArrayRef<uint8_t> Val) { 749 return Offsets.find(Val)->second; 750 } 751 752 template <class ELFT> 753 StringTableSection<ELFT>::StringTableSection(StringRef Name, bool Dynamic) 754 : OutputSectionBase<ELFT>(Name, llvm::ELF::SHT_STRTAB, 755 Dynamic ? (uintX_t)llvm::ELF::SHF_ALLOC : 0), 756 Dynamic(Dynamic) { 757 this->Header.sh_addralign = 1; 758 } 759 760 template <class ELFT> void StringTableSection<ELFT>::writeTo(uint8_t *Buf) { 761 StringRef Data = StrTabBuilder.data(); 762 memcpy(Buf, Data.data(), Data.size()); 763 } 764 765 template <class ELFT> bool lld::elf2::includeInSymtab(const SymbolBody &B) { 766 if (!B.isUsedInRegularObj()) 767 return false; 768 769 // Don't include synthetic symbols like __init_array_start in every output. 770 if (auto *U = dyn_cast<DefinedAbsolute<ELFT>>(&B)) 771 if (&U->Sym == &DefinedAbsolute<ELFT>::IgnoreUndef) 772 return false; 773 774 return true; 775 } 776 777 bool lld::elf2::includeInDynamicSymtab(const SymbolBody &B) { 778 uint8_t V = B.getVisibility(); 779 if (V != STV_DEFAULT && V != STV_PROTECTED) 780 return false; 781 782 if (Config->ExportDynamic || Config->Shared) 783 return true; 784 return B.isUsedInDynamicReloc(); 785 } 786 787 bool lld::elf2::includeInGnuHashTable(const SymbolBody &B) { 788 // Assume that includeInDynamicSymtab() is already checked. 789 return !B.isUndefined(); 790 } 791 792 template <class ELFT> 793 bool lld::elf2::shouldKeepInSymtab(const ObjectFile<ELFT> &File, 794 StringRef SymName, 795 const typename ELFFile<ELFT>::Elf_Sym &Sym) { 796 if (Sym.getType() == STT_SECTION) 797 return false; 798 799 // If sym references a section in a discarded group, don't keep it. 800 if (File.getSection(Sym) == &InputSection<ELFT>::Discarded) 801 return false; 802 803 if (Config->DiscardNone) 804 return true; 805 806 // ELF defines dynamic locals as symbols which name starts with ".L". 807 return !(Config->DiscardLocals && SymName.startswith(".L")); 808 } 809 810 template <class ELFT> 811 SymbolTableSection<ELFT>::SymbolData::SymbolData(SymbolBody *Body, 812 bool HasGnuHash) 813 : Body(Body), HasGnuHash(HasGnuHash), 814 GnuHash(HasGnuHash ? hashGnu(Body->getName()) : 0) {} 815 816 template <class ELFT> 817 SymbolTableSection<ELFT>::SymbolTableSection( 818 SymbolTable<ELFT> &Table, StringTableSection<ELFT> &StrTabSec) 819 : OutputSectionBase<ELFT>( 820 StrTabSec.isDynamic() ? ".dynsym" : ".symtab", 821 StrTabSec.isDynamic() ? llvm::ELF::SHT_DYNSYM : llvm::ELF::SHT_SYMTAB, 822 StrTabSec.isDynamic() ? (uintX_t)llvm::ELF::SHF_ALLOC : 0), 823 Table(Table), StrTabSec(StrTabSec) { 824 typedef OutputSectionBase<ELFT> Base; 825 typename Base::Elf_Shdr &Header = this->Header; 826 827 Header.sh_entsize = sizeof(Elf_Sym); 828 Header.sh_addralign = ELFT::Is64Bits ? 8 : 4; 829 } 830 831 template <class ELFT> void SymbolTableSection<ELFT>::finalize() { 832 this->Header.sh_size = getNumSymbols() * sizeof(Elf_Sym); 833 this->Header.sh_link = StrTabSec.SectionIndex; 834 this->Header.sh_info = NumLocals + 1; 835 836 if (!StrTabSec.isDynamic()) { 837 std::stable_sort(Symbols.begin(), Symbols.end(), 838 [](const SymbolData &L, const SymbolData &R) { 839 return getSymbolBinding(L.Body) == STB_LOCAL && 840 getSymbolBinding(R.Body) != STB_LOCAL; 841 }); 842 return; 843 } 844 if (NumGnuHashed) { 845 unsigned NBuckets = GnuHashTableSection<ELFT>::calcNBuckets(NumGnuHashed); 846 std::stable_sort(Symbols.begin(), Symbols.end(), 847 [NBuckets](const SymbolData &L, const SymbolData &R) { 848 if (!L.HasGnuHash || !R.HasGnuHash) 849 return R.HasGnuHash; 850 return L.GnuHash % NBuckets < R.GnuHash % NBuckets; 851 }); 852 } 853 size_t I = 0; 854 for (const SymbolData &Item : Symbols) 855 Item.Body->setDynamicSymbolTableIndex(++I); 856 } 857 858 template <class ELFT> 859 void SymbolTableSection<ELFT>::addLocalSymbol(StringRef Name) { 860 StrTabSec.add(Name); 861 ++NumVisible; 862 ++NumLocals; 863 } 864 865 template <class ELFT> 866 void SymbolTableSection<ELFT>::addSymbol(SymbolBody *Body) { 867 StrTabSec.add(Body->getName()); 868 const bool HasGnuHash = StrTabSec.isDynamic() && Out<ELFT>::GnuHashTab && 869 includeInGnuHashTable(*Body); 870 Symbols.emplace_back(Body, HasGnuHash); 871 ++NumVisible; 872 if (HasGnuHash) 873 ++NumGnuHashed; 874 } 875 876 template <class ELFT> void SymbolTableSection<ELFT>::writeTo(uint8_t *Buf) { 877 Buf += sizeof(Elf_Sym); 878 879 // All symbols with STB_LOCAL binding precede the weak and global symbols. 880 // .dynsym only contains global symbols. 881 if (!Config->DiscardAll && !StrTabSec.isDynamic()) 882 writeLocalSymbols(Buf); 883 884 writeGlobalSymbols(Buf); 885 } 886 887 template <class ELFT> 888 void SymbolTableSection<ELFT>::writeLocalSymbols(uint8_t *&Buf) { 889 // Iterate over all input object files to copy their local symbols 890 // to the output symbol table pointed by Buf. 891 for (const std::unique_ptr<ObjectFile<ELFT>> &File : Table.getObjectFiles()) { 892 Elf_Sym_Range Syms = File->getLocalSymbols(); 893 for (const Elf_Sym &Sym : Syms) { 894 ErrorOr<StringRef> SymNameOrErr = Sym.getName(File->getStringTable()); 895 error(SymNameOrErr); 896 StringRef SymName = *SymNameOrErr; 897 if (!shouldKeepInSymtab<ELFT>(*File, SymName, Sym)) 898 continue; 899 900 auto *ESym = reinterpret_cast<Elf_Sym *>(Buf); 901 uintX_t VA = 0; 902 if (Sym.st_shndx == SHN_ABS) { 903 ESym->st_shndx = SHN_ABS; 904 VA = Sym.st_value; 905 } else { 906 const InputSectionBase<ELFT> *Section = File->getSection(Sym); 907 if (!Section->isLive()) 908 continue; 909 const OutputSectionBase<ELFT> *OutSec = Section->OutSec; 910 ESym->st_shndx = OutSec->SectionIndex; 911 VA += OutSec->getVA() + Section->getOffset(Sym); 912 } 913 ESym->st_name = StrTabSec.getFileOff(SymName); 914 ESym->st_size = Sym.st_size; 915 ESym->setBindingAndType(Sym.getBinding(), Sym.getType()); 916 ESym->st_value = VA; 917 Buf += sizeof(*ESym); 918 } 919 } 920 } 921 922 template <class ELFT> 923 void SymbolTableSection<ELFT>::writeGlobalSymbols(uint8_t *Buf) { 924 // Write the internal symbol table contents to the output symbol table 925 // pointed by Buf. 926 auto *ESym = reinterpret_cast<Elf_Sym *>(Buf); 927 for (const SymbolData &Item : Symbols) { 928 SymbolBody *Body = Item.Body; 929 const OutputSectionBase<ELFT> *OutSec = nullptr; 930 931 switch (Body->kind()) { 932 case SymbolBody::DefinedSyntheticKind: 933 OutSec = &cast<DefinedSynthetic<ELFT>>(Body)->Section; 934 break; 935 case SymbolBody::DefinedRegularKind: { 936 auto *Sym = cast<DefinedRegular<ELFT>>(Body->repl()); 937 if (!Sym->Section.isLive()) 938 continue; 939 OutSec = Sym->Section.OutSec; 940 break; 941 } 942 case SymbolBody::DefinedCommonKind: 943 OutSec = Out<ELFT>::Bss; 944 break; 945 case SymbolBody::UndefinedKind: 946 case SymbolBody::DefinedAbsoluteKind: 947 case SymbolBody::SharedKind: 948 case SymbolBody::LazyKind: 949 break; 950 } 951 952 StringRef Name = Body->getName(); 953 ESym->st_name = StrTabSec.getFileOff(Name); 954 955 unsigned char Type = STT_NOTYPE; 956 uintX_t Size = 0; 957 if (const auto *EBody = dyn_cast<ELFSymbolBody<ELFT>>(Body)) { 958 const Elf_Sym &InputSym = EBody->Sym; 959 Type = InputSym.getType(); 960 Size = InputSym.st_size; 961 } 962 963 ESym->setBindingAndType(getSymbolBinding(Body), Type); 964 ESym->st_size = Size; 965 ESym->setVisibility(Body->getVisibility()); 966 ESym->st_value = getSymVA<ELFT>(*Body); 967 968 if (isa<DefinedAbsolute<ELFT>>(Body)) 969 ESym->st_shndx = SHN_ABS; 970 else if (OutSec) 971 ESym->st_shndx = OutSec->SectionIndex; 972 973 ++ESym; 974 } 975 } 976 977 template <class ELFT> 978 uint8_t SymbolTableSection<ELFT>::getSymbolBinding(SymbolBody *Body) { 979 uint8_t Visibility = Body->getVisibility(); 980 if (Visibility != STV_DEFAULT && Visibility != STV_PROTECTED) 981 return STB_LOCAL; 982 if (const auto *EBody = dyn_cast<ELFSymbolBody<ELFT>>(Body)) 983 return EBody->Sym.getBinding(); 984 return Body->isWeak() ? STB_WEAK : STB_GLOBAL; 985 } 986 987 template <class ELFT> 988 ArrayRef<typename SymbolTableSection<ELFT>::SymbolData> 989 SymbolTableSection<ELFT>::getGnuHashSymbols() const { 990 return getSymbols().slice(Symbols.size() - NumGnuHashed); 991 } 992 993 namespace lld { 994 namespace elf2 { 995 template class OutputSectionBase<ELF32LE>; 996 template class OutputSectionBase<ELF32BE>; 997 template class OutputSectionBase<ELF64LE>; 998 template class OutputSectionBase<ELF64BE>; 999 1000 template class GotPltSection<ELF32LE>; 1001 template class GotPltSection<ELF32BE>; 1002 template class GotPltSection<ELF64LE>; 1003 template class GotPltSection<ELF64BE>; 1004 1005 template class GotSection<ELF32LE>; 1006 template class GotSection<ELF32BE>; 1007 template class GotSection<ELF64LE>; 1008 template class GotSection<ELF64BE>; 1009 1010 template class PltSection<ELF32LE>; 1011 template class PltSection<ELF32BE>; 1012 template class PltSection<ELF64LE>; 1013 template class PltSection<ELF64BE>; 1014 1015 template class RelocationSection<ELF32LE>; 1016 template class RelocationSection<ELF32BE>; 1017 template class RelocationSection<ELF64LE>; 1018 template class RelocationSection<ELF64BE>; 1019 1020 template class InterpSection<ELF32LE>; 1021 template class InterpSection<ELF32BE>; 1022 template class InterpSection<ELF64LE>; 1023 template class InterpSection<ELF64BE>; 1024 1025 template class GnuHashTableSection<ELF32LE>; 1026 template class GnuHashTableSection<ELF32BE>; 1027 template class GnuHashTableSection<ELF64LE>; 1028 template class GnuHashTableSection<ELF64BE>; 1029 1030 template class HashTableSection<ELF32LE>; 1031 template class HashTableSection<ELF32BE>; 1032 template class HashTableSection<ELF64LE>; 1033 template class HashTableSection<ELF64BE>; 1034 1035 template class DynamicSection<ELF32LE>; 1036 template class DynamicSection<ELF32BE>; 1037 template class DynamicSection<ELF64LE>; 1038 template class DynamicSection<ELF64BE>; 1039 1040 template class OutputSection<ELF32LE>; 1041 template class OutputSection<ELF32BE>; 1042 template class OutputSection<ELF64LE>; 1043 template class OutputSection<ELF64BE>; 1044 1045 template class MergeOutputSection<ELF32LE>; 1046 template class MergeOutputSection<ELF32BE>; 1047 template class MergeOutputSection<ELF64LE>; 1048 template class MergeOutputSection<ELF64BE>; 1049 1050 template class StringTableSection<ELF32LE>; 1051 template class StringTableSection<ELF32BE>; 1052 template class StringTableSection<ELF64LE>; 1053 template class StringTableSection<ELF64BE>; 1054 1055 template class SymbolTableSection<ELF32LE>; 1056 template class SymbolTableSection<ELF32BE>; 1057 template class SymbolTableSection<ELF64LE>; 1058 template class SymbolTableSection<ELF64BE>; 1059 1060 template ELFFile<ELF32LE>::uintX_t getSymVA<ELF32LE>(const SymbolBody &); 1061 template ELFFile<ELF32BE>::uintX_t getSymVA<ELF32BE>(const SymbolBody &); 1062 template ELFFile<ELF64LE>::uintX_t getSymVA<ELF64LE>(const SymbolBody &); 1063 template ELFFile<ELF64BE>::uintX_t getSymVA<ELF64BE>(const SymbolBody &); 1064 1065 template ELFFile<ELF32LE>::uintX_t 1066 getLocalRelTarget(const ObjectFile<ELF32LE> &, 1067 const ELFFile<ELF32LE>::Elf_Rel &); 1068 template ELFFile<ELF32BE>::uintX_t 1069 getLocalRelTarget(const ObjectFile<ELF32BE> &, 1070 const ELFFile<ELF32BE>::Elf_Rel &); 1071 template ELFFile<ELF64LE>::uintX_t 1072 getLocalRelTarget(const ObjectFile<ELF64LE> &, 1073 const ELFFile<ELF64LE>::Elf_Rel &); 1074 template ELFFile<ELF64BE>::uintX_t 1075 getLocalRelTarget(const ObjectFile<ELF64BE> &, 1076 const ELFFile<ELF64BE>::Elf_Rel &); 1077 1078 template ELFFile<ELF32LE>::uintX_t 1079 getLocalRelTarget(const ObjectFile<ELF32LE> &, 1080 const ELFFile<ELF32LE>::Elf_Rela &); 1081 template ELFFile<ELF32BE>::uintX_t 1082 getLocalRelTarget(const ObjectFile<ELF32BE> &, 1083 const ELFFile<ELF32BE>::Elf_Rela &); 1084 template ELFFile<ELF64LE>::uintX_t 1085 getLocalRelTarget(const ObjectFile<ELF64LE> &, 1086 const ELFFile<ELF64LE>::Elf_Rela &); 1087 template ELFFile<ELF64BE>::uintX_t 1088 getLocalRelTarget(const ObjectFile<ELF64BE> &, 1089 const ELFFile<ELF64BE>::Elf_Rela &); 1090 1091 template bool includeInSymtab<ELF32LE>(const SymbolBody &); 1092 template bool includeInSymtab<ELF32BE>(const SymbolBody &); 1093 template bool includeInSymtab<ELF64LE>(const SymbolBody &); 1094 template bool includeInSymtab<ELF64BE>(const SymbolBody &); 1095 1096 template bool shouldKeepInSymtab<ELF32LE>(const ObjectFile<ELF32LE> &, 1097 StringRef, 1098 const ELFFile<ELF32LE>::Elf_Sym &); 1099 template bool shouldKeepInSymtab<ELF32BE>(const ObjectFile<ELF32BE> &, 1100 StringRef, 1101 const ELFFile<ELF32BE>::Elf_Sym &); 1102 template bool shouldKeepInSymtab<ELF64LE>(const ObjectFile<ELF64LE> &, 1103 StringRef, 1104 const ELFFile<ELF64LE>::Elf_Sym &); 1105 template bool shouldKeepInSymtab<ELF64BE>(const ObjectFile<ELF64BE> &, 1106 StringRef, 1107 const ELFFile<ELF64BE>::Elf_Sym &); 1108 } 1109 } 1110