diff options
Diffstat (limited to 'lld/ELF')
| -rw-r--r-- | lld/ELF/InputSection.cpp | 24 | ||||
| -rw-r--r-- | lld/ELF/InputSection.h | 9 | ||||
| -rw-r--r-- | lld/ELF/OutputSections.cpp | 170 | ||||
| -rw-r--r-- | lld/ELF/OutputSections.h | 57 | ||||
| -rw-r--r-- | lld/ELF/Writer.cpp | 166 |
5 files changed, 217 insertions, 209 deletions
diff --git a/lld/ELF/InputSection.cpp b/lld/ELF/InputSection.cpp index 7561f377dd7..3664404b8ce 100644 --- a/lld/ELF/InputSection.cpp +++ b/lld/ELF/InputSection.cpp @@ -29,15 +29,13 @@ template <class ELFT> template <bool isRela> void InputSection<ELFT>::relocate( uint8_t *Buf, iterator_range<const Elf_Rel_Impl<ELFT, isRela> *> Rels, - const ObjectFile<ELFT> &File, uintX_t BaseAddr, - const OutputSection<ELFT> &BssSec, const PltSection<ELFT> &PltSec, - const GotSection<ELFT> &GotSec) { + const ObjectFile<ELFT> &File, uintX_t BaseAddr) { typedef Elf_Rel_Impl<ELFT, isRela> RelType; bool IsMips64EL = File.getObj().isMips64EL(); for (const RelType &RI : Rels) { uint32_t SymIndex = RI.getSymbol(IsMips64EL); uint32_t Type = RI.getType(IsMips64EL); - uintX_t GotVA = GotSec.getVA(); + uintX_t GotVA = Out<ELFT>::Got->getVA(); uintX_t SymVA; // Handle relocations for local symbols -- they never get @@ -50,12 +48,12 @@ void InputSection<ELFT>::relocate( SymVA = getLocalSymVA(Sym, File); } else { SymbolBody &Body = *File.getSymbolBody(SymIndex); - SymVA = getSymVA<ELFT>(Body, BssSec); + SymVA = getSymVA<ELFT>(Body); if (Target->relocNeedsPlt(Type, Body)) { - SymVA = PltSec.getEntryAddr(Body); + SymVA = Out<ELFT>::Plt->getEntryAddr(Body); Type = Target->getPCRelReloc(); } else if (Target->relocNeedsGot(Type, Body)) { - SymVA = GotSec.getEntryAddr(Body); + SymVA = Out<ELFT>::Got->getEntryAddr(Body); Type = Target->getGotRefReloc(); } else if (Target->relocPointsToGot(Type)) { SymVA = GotVA; @@ -70,11 +68,7 @@ void InputSection<ELFT>::relocate( } } -template <class ELFT> -void InputSection<ELFT>::writeTo(uint8_t *Buf, - const OutputSection<ELFT> &BssSec, - const PltSection<ELFT> &PltSec, - const GotSection<ELFT> &GotSec) { +template <class ELFT> void InputSection<ELFT>::writeTo(uint8_t *Buf) { if (Header->sh_type == SHT_NOBITS) return; // Copy section contents from source object file to output file. @@ -88,11 +82,9 @@ void InputSection<ELFT>::writeTo(uint8_t *Buf, // Iterate over all relocation sections that apply to this section. for (const Elf_Shdr *RelSec : RelocSections) { if (RelSec->sh_type == SHT_RELA) - relocate(Base, EObj.relas(RelSec), *File, BaseAddr, BssSec, PltSec, - GotSec); + relocate(Base, EObj.relas(RelSec), *File, BaseAddr); else - relocate(Base, EObj.rels(RelSec), *File, BaseAddr, BssSec, PltSec, - GotSec); + relocate(Base, EObj.rels(RelSec), *File, BaseAddr); } } diff --git a/lld/ELF/InputSection.h b/lld/ELF/InputSection.h index b25d77015e3..53e0f9f9678 100644 --- a/lld/ELF/InputSection.h +++ b/lld/ELF/InputSection.h @@ -18,8 +18,6 @@ namespace elf2 { template <class ELFT> class ObjectFile; template <class ELFT> class OutputSection; -template <class ELFT> class PltSection; -template <class ELFT> class GotSection; // This corresponds to a section of an input file. template <class ELFT> class InputSection { @@ -37,8 +35,7 @@ public: // Write this section to a mmap'ed file, assuming Buf is pointing to // beginning of the output section. - void writeTo(uint8_t *Buf, const OutputSection<ELFT> &BssSec, - const PltSection<ELFT> &PltSec, const GotSection<ELFT> &GotSec); + void writeTo(uint8_t *Buf); StringRef getSectionName() const; const Elf_Shdr *getSectionHdr() const { return Header; } @@ -64,9 +61,7 @@ private: void relocate(uint8_t *Buf, llvm::iterator_range< const llvm::object::Elf_Rel_Impl<ELFT, isRela> *> Rels, - const ObjectFile<ELFT> &File, uintX_t BaseAddr, - const OutputSection<ELFT> &BssSec, - const PltSection<ELFT> &PltSec, const GotSection<ELFT> &GotSec); + const ObjectFile<ELFT> &File, uintX_t BaseAddr); // The offset from beginning of the output sections this section was assigned // to. The writer sets a value. diff --git a/lld/ELF/OutputSections.cpp b/lld/ELF/OutputSections.cpp index 00a244a2a46..90517b621ec 100644 --- a/lld/ELF/OutputSections.cpp +++ b/lld/ELF/OutputSections.cpp @@ -20,6 +20,51 @@ using namespace llvm::ELF; using namespace lld; using namespace lld::elf2; +template <> DynamicSection<ELF32BE> *Out<ELF32BE>::Dynamic = nullptr; +template <> DynamicSection<ELF32LE> *Out<ELF32LE>::Dynamic = nullptr; +template <> DynamicSection<ELF64BE> *Out<ELF64BE>::Dynamic = nullptr; +template <> DynamicSection<ELF64LE> *Out<ELF64LE>::Dynamic = nullptr; +template <> GotSection<ELF32BE> *Out<ELF32BE>::Got = nullptr; +template <> GotSection<ELF32LE> *Out<ELF32LE>::Got = nullptr; +template <> GotSection<ELF64BE> *Out<ELF64BE>::Got = nullptr; +template <> GotSection<ELF64LE> *Out<ELF64LE>::Got = nullptr; +template <> HashTableSection<ELF32BE> *Out<ELF32BE>::HashTab = nullptr; +template <> HashTableSection<ELF32LE> *Out<ELF32LE>::HashTab = nullptr; +template <> HashTableSection<ELF64BE> *Out<ELF64BE>::HashTab = nullptr; +template <> HashTableSection<ELF64LE> *Out<ELF64LE>::HashTab = nullptr; +template <> InterpSection<false> *Out<ELF32BE>::Interp = nullptr; +template <> InterpSection<false> *Out<ELF32LE>::Interp = nullptr; +template <> InterpSection<true> *Out<ELF64BE>::Interp = nullptr; +template <> InterpSection<true> *Out<ELF64LE>::Interp = nullptr; +template <> OutputSection<ELF32BE> *Out<ELF32BE>::Bss = nullptr; +template <> OutputSection<ELF32LE> *Out<ELF32LE>::Bss = nullptr; +template <> OutputSection<ELF64BE> *Out<ELF64BE>::Bss = nullptr; +template <> OutputSection<ELF64LE> *Out<ELF64LE>::Bss = nullptr; +template <> PltSection<ELF32BE> *Out<ELF32BE>::Plt = nullptr; +template <> PltSection<ELF32LE> *Out<ELF32LE>::Plt = nullptr; +template <> PltSection<ELF64BE> *Out<ELF64BE>::Plt = nullptr; +template <> PltSection<ELF64LE> *Out<ELF64LE>::Plt = nullptr; +template <> RelocationSection<ELF32BE> *Out<ELF32BE>::RelaDyn = nullptr; +template <> RelocationSection<ELF32LE> *Out<ELF32LE>::RelaDyn = nullptr; +template <> RelocationSection<ELF64BE> *Out<ELF64BE>::RelaDyn = nullptr; +template <> RelocationSection<ELF64LE> *Out<ELF64LE>::RelaDyn = nullptr; +template <> StringTableSection<false> *Out<ELF32BE>::DynStrTab = nullptr; +template <> StringTableSection<false> *Out<ELF32LE>::DynStrTab = nullptr; +template <> StringTableSection<true> *Out<ELF64BE>::DynStrTab = nullptr; +template <> StringTableSection<true> *Out<ELF64LE>::DynStrTab = nullptr; +template <> StringTableSection<false> *Out<ELF32BE>::StrTab = nullptr; +template <> StringTableSection<false> *Out<ELF32LE>::StrTab = nullptr; +template <> StringTableSection<true> *Out<ELF64BE>::StrTab = nullptr; +template <> StringTableSection<true> *Out<ELF64LE>::StrTab = nullptr; +template <> SymbolTableSection<ELF32BE> *Out<ELF32BE>::DynSymTab = nullptr; +template <> SymbolTableSection<ELF32LE> *Out<ELF32LE>::DynSymTab = nullptr; +template <> SymbolTableSection<ELF64BE> *Out<ELF64BE>::DynSymTab = nullptr; +template <> SymbolTableSection<ELF64LE> *Out<ELF64LE>::DynSymTab = nullptr; +template <> SymbolTableSection<ELF32BE> *Out<ELF32BE>::SymTab = nullptr; +template <> SymbolTableSection<ELF32LE> *Out<ELF32LE>::SymTab = nullptr; +template <> SymbolTableSection<ELF64BE> *Out<ELF64BE>::SymTab = nullptr; +template <> SymbolTableSection<ELF64LE> *Out<ELF64LE>::SymTab = nullptr; + template <bool Is64Bits> OutputSectionBase<Is64Bits>::OutputSectionBase(StringRef Name, uint32_t sh_type, uintX_t sh_flags) @@ -30,11 +75,10 @@ OutputSectionBase<Is64Bits>::OutputSectionBase(StringRef Name, uint32_t sh_type, } template <class ELFT> -GotSection<ELFT>::GotSection(const OutputSection<ELFT> &BssSec) +GotSection<ELFT>::GotSection() : OutputSectionBase<ELFT::Is64Bits>(".got", llvm::ELF::SHT_PROGBITS, llvm::ELF::SHF_ALLOC | - llvm::ELF::SHF_WRITE), - BssSec(BssSec) { + llvm::ELF::SHF_WRITE) { this->Header.sh_addralign = this->getAddrSize(); } @@ -55,24 +99,23 @@ template <class ELFT> void GotSection<ELFT>::writeTo(uint8_t *Buf) { Buf += sizeof(uintX_t); if (canBePreempted(B)) continue; // The dynamic linker will take care of it. - uintX_t VA = getSymVA(*B, BssSec); + uintX_t VA = getSymVA<ELFT>(*B); write<uintX_t, ELFT::TargetEndianness, sizeof(uintX_t)>(Entry, VA); } } template <class ELFT> -PltSection<ELFT>::PltSection(const GotSection<ELFT> &GotSec) +PltSection<ELFT>::PltSection() : OutputSectionBase<ELFT::Is64Bits>(".plt", llvm::ELF::SHT_PROGBITS, llvm::ELF::SHF_ALLOC | - llvm::ELF::SHF_EXECINSTR), - GotSec(GotSec) { + llvm::ELF::SHF_EXECINSTR) { this->Header.sh_addralign = 16; } template <class ELFT> void PltSection<ELFT>::writeTo(uint8_t *Buf) { uintptr_t Start = reinterpret_cast<uintptr_t>(Buf); for (const SymbolBody *E : Entries) { - uint64_t GotEntryAddr = GotSec.getEntryAddr(*E); + uint64_t GotEntryAddr = Out<ELFT>::Got->getEntryAddr(*E); uintptr_t InstPos = reinterpret_cast<uintptr_t>(Buf); uint64_t PltEntryAddr = (InstPos - Start) + this->getVA(); Target->writePltEntry(Buf, GotEntryAddr, PltEntryAddr); @@ -92,15 +135,12 @@ PltSection<ELFT>::getEntryAddr(const SymbolBody &B) const { } template <class ELFT> -RelocationSection<ELFT>::RelocationSection(SymbolTableSection<ELFT> &DynSymSec, - const GotSection<ELFT> &GotSec, - const OutputSection<ELFT> &BssSec, - bool IsRela) +RelocationSection<ELFT>::RelocationSection(bool IsRela) : OutputSectionBase<ELFT::Is64Bits>(IsRela ? ".rela.dyn" : ".rel.dyn", IsRela ? llvm::ELF::SHT_RELA : llvm::ELF::SHT_REL, llvm::ELF::SHF_ALLOC), - DynSymSec(DynSymSec), GotSec(GotSec), BssSec(BssSec), IsRela(IsRela) { + IsRela(IsRela) { this->Header.sh_entsize = IsRela ? sizeof(Elf_Rela) : sizeof(Elf_Rel); this->Header.sh_addralign = ELFT::Is64Bits ? 8 : 4; } @@ -127,7 +167,7 @@ template <class ELFT> void RelocationSection<ELFT>::writeTo(uint8_t *Buf) { if (!CanBePreempted) { if (IsRela) { if (Body) - Addend += getSymVA(cast<ELFSymbolBody<ELFT>>(*Body), BssSec); + Addend += getSymVA<ELFT>(cast<ELFSymbolBody<ELFT>>(*Body)); else Addend += getLocalSymVA( Obj.getRelocationSymbol(&RI, File.getSymbolTable()), File); @@ -136,7 +176,7 @@ template <class ELFT> void RelocationSection<ELFT>::writeTo(uint8_t *Buf) { } if (Body && Target->relocNeedsGot(Type, *Body)) { - P->r_offset = GotSec.getEntryAddr(*Body); + P->r_offset = Out<ELFT>::Got->getEntryAddr(*Body); if (CanBePreempted) P->setSymbolAndType(Body->getDynamicSymbolTableIndex(), Target->getGotReloc(), IsMips64EL); @@ -155,7 +195,7 @@ template <class ELFT> void RelocationSection<ELFT>::writeTo(uint8_t *Buf) { } template <class ELFT> void RelocationSection<ELFT>::finalize() { - this->Header.sh_link = DynSymSec.getSectionIndex(); + this->Header.sh_link = Out<ELFT>::DynSymTab->getSectionIndex(); this->Header.sh_size = Relocs.size() * this->Header.sh_entsize; } @@ -188,37 +228,36 @@ template <bool Is64Bits> void InterpSection<Is64Bits>::writeTo(uint8_t *Buf) { } template <class ELFT> -HashTableSection<ELFT>::HashTableSection(SymbolTableSection<ELFT> &DynSymSec) +HashTableSection<ELFT>::HashTableSection() : OutputSectionBase<ELFT::Is64Bits>(".hash", llvm::ELF::SHT_HASH, - llvm::ELF::SHF_ALLOC), - DynSymSec(DynSymSec) { + llvm::ELF::SHF_ALLOC) { this->Header.sh_entsize = sizeof(Elf_Word); this->Header.sh_addralign = sizeof(Elf_Word); } template <class ELFT> void HashTableSection<ELFT>::addSymbol(SymbolBody *S) { StringRef Name = S->getName(); - DynSymSec.addSymbol(Name); + Out<ELFT>::DynSymTab->addSymbol(Name); Hashes.push_back(hash(Name)); S->setDynamicSymbolTableIndex(Hashes.size()); } template <class ELFT> void HashTableSection<ELFT>::finalize() { - this->Header.sh_link = DynSymSec.getSectionIndex(); + this->Header.sh_link = Out<ELFT>::DynSymTab->getSectionIndex(); - assert(DynSymSec.getNumSymbols() == Hashes.size() + 1); + assert(Out<ELFT>::DynSymTab->getNumSymbols() == Hashes.size() + 1); unsigned NumEntries = 2; // nbucket and nchain. - NumEntries += DynSymSec.getNumSymbols(); // The chain entries. + NumEntries += Out<ELFT>::DynSymTab->getNumSymbols(); // The chain entries. // Create as many buckets as there are symbols. // FIXME: This is simplistic. We can try to optimize it, but implementing // support for SHT_GNU_HASH is probably even more profitable. - NumEntries += DynSymSec.getNumSymbols(); + NumEntries += Out<ELFT>::DynSymTab->getNumSymbols(); this->Header.sh_size = NumEntries * sizeof(Elf_Word); } template <class ELFT> void HashTableSection<ELFT>::writeTo(uint8_t *Buf) { - unsigned NumSymbols = DynSymSec.getNumSymbols(); + unsigned NumSymbols = Out<ELFT>::DynSymTab->getNumSymbols(); auto *P = reinterpret_cast<Elf_Word *>(Buf); *P++ = NumSymbols; // nbucket *P++ = NumSymbols; // nchain @@ -234,16 +273,11 @@ template <class ELFT> void HashTableSection<ELFT>::writeTo(uint8_t *Buf) { } template <class ELFT> -DynamicSection<ELFT>::DynamicSection(SymbolTable &SymTab, - HashTableSection<ELFT> &HashSec, - RelocationSection<ELFT> &RelaDynSec, - const OutputSection<ELFT> &BssSec) +DynamicSection<ELFT>::DynamicSection(SymbolTable &SymTab) : OutputSectionBase<ELFT::Is64Bits>(".dynamic", llvm::ELF::SHT_DYNAMIC, llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_WRITE), - HashSec(HashSec), DynSymSec(HashSec.getDynSymSec()), - DynStrSec(DynSymSec.getStrTabSec()), RelaDynSec(RelaDynSec), - BssSec(BssSec), SymTab(SymTab) { + SymTab(SymTab) { typename Base::HeaderT &Header = this->Header; Header.sh_addralign = ELFT::Is64Bits ? 8 : 4; Header.sh_entsize = ELFT::Is64Bits ? 16 : 8; @@ -254,10 +288,10 @@ template <class ELFT> void DynamicSection<ELFT>::finalize() { return; // Already finalized. typename Base::HeaderT &Header = this->Header; - Header.sh_link = DynStrSec.getSectionIndex(); + Header.sh_link = Out<ELFT>::DynStrTab->getSectionIndex(); unsigned NumEntries = 0; - if (RelaDynSec.hasRelocs()) { + if (Out<ELFT>::RelaDyn->hasRelocs()) { ++NumEntries; // DT_RELA / DT_REL ++NumEntries; // DT_RELASZ / DT_RELSZ ++NumEntries; // DT_RELAENT / DT_RELENT @@ -270,12 +304,12 @@ template <class ELFT> void DynamicSection<ELFT>::finalize() { if (!Config->RPath.empty()) { ++NumEntries; // DT_RUNPATH / DT_RPATH - DynStrSec.add(Config->RPath); + Out<ELFT>::DynStrTab->add(Config->RPath); } if (!Config->SoName.empty()) { ++NumEntries; // DT_SONAME - DynStrSec.add(Config->SoName); + Out<ELFT>::DynStrTab->add(Config->SoName); } if (PreInitArraySec) @@ -288,7 +322,7 @@ template <class ELFT> void DynamicSection<ELFT>::finalize() { const std::vector<std::unique_ptr<SharedFileBase>> &SharedFiles = SymTab.getSharedFiles(); for (const std::unique_ptr<SharedFileBase> &File : SharedFiles) - DynStrSec.add(File->getSoName()); + Out<ELFT>::DynStrTab->add(File->getSoName()); NumEntries += SharedFiles.size(); if (Symbol *S = SymTab.getSymbols().lookup(Config->Init)) @@ -322,19 +356,19 @@ template <class ELFT> void DynamicSection<ELFT>::writeTo(uint8_t *Buf) { ++P; }; - if (RelaDynSec.hasRelocs()) { - bool IsRela = RelaDynSec.isRela(); - WritePtr(IsRela ? DT_RELA : DT_REL, RelaDynSec.getVA()); - WriteVal(IsRela ? DT_RELASZ : DT_RELSZ, RelaDynSec.getSize()); + if (Out<ELFT>::RelaDyn->hasRelocs()) { + bool IsRela = Out<ELFT>::RelaDyn->isRela(); + WritePtr(IsRela ? DT_RELA : DT_REL, Out<ELFT>::RelaDyn->getVA()); + WriteVal(IsRela ? DT_RELASZ : DT_RELSZ, Out<ELFT>::RelaDyn->getSize()); WriteVal(IsRela ? DT_RELAENT : DT_RELENT, IsRela ? sizeof(Elf_Rela) : sizeof(Elf_Rel)); } - WritePtr(DT_SYMTAB, DynSymSec.getVA()); + WritePtr(DT_SYMTAB, Out<ELFT>::DynSymTab->getVA()); WritePtr(DT_SYMENT, sizeof(Elf_Sym)); - WritePtr(DT_STRTAB, DynStrSec.getVA()); - WriteVal(DT_STRSZ, DynStrSec.data().size()); - WritePtr(DT_HASH, HashSec.getVA()); + WritePtr(DT_STRTAB, Out<ELFT>::DynStrTab->getVA()); + WriteVal(DT_STRSZ, Out<ELFT>::DynStrTab->data().size()); + WritePtr(DT_HASH, Out<ELFT>::HashTab->getVA()); if (!Config->RPath.empty()) @@ -347,10 +381,10 @@ template <class ELFT> void DynamicSection<ELFT>::writeTo(uint8_t *Buf) { // dependencies of the object it's contained in, while // DT_RPATH is used for indirect dependencies as well. WriteVal(Config->EnableNewDtags ? DT_RUNPATH : DT_RPATH, - DynStrSec.getFileOff(Config->RPath)); + Out<ELFT>::DynStrTab->getFileOff(Config->RPath)); if (!Config->SoName.empty()) - WriteVal(DT_SONAME, DynStrSec.getFileOff(Config->SoName)); + WriteVal(DT_SONAME, Out<ELFT>::DynStrTab->getFileOff(Config->SoName)); auto WriteArray = [&](int32_t T1, int32_t T2, const OutputSection<ELFT> *Sec) { @@ -366,12 +400,12 @@ template <class ELFT> void DynamicSection<ELFT>::writeTo(uint8_t *Buf) { const std::vector<std::unique_ptr<SharedFileBase>> &SharedFiles = SymTab.getSharedFiles(); for (const std::unique_ptr<SharedFileBase> &File : SharedFiles) - WriteVal(DT_NEEDED, DynStrSec.getFileOff(File->getSoName())); + WriteVal(DT_NEEDED, Out<ELFT>::DynStrTab->getFileOff(File->getSoName())); if (InitSym) - WritePtr(DT_INIT, getSymVA(*InitSym, BssSec)); + WritePtr(DT_INIT, getSymVA<ELFT>(*InitSym)); if (FiniSym) - WritePtr(DT_FINI, getSymVA(*FiniSym, BssSec)); + WritePtr(DT_FINI, getSymVA<ELFT>(*FiniSym)); if (Config->ZNow) WriteVal(DT_FLAGS_1, DF_1_NOW); @@ -380,13 +414,9 @@ template <class ELFT> void DynamicSection<ELFT>::writeTo(uint8_t *Buf) { } template <class ELFT> -OutputSection<ELFT>::OutputSection(const PltSection<ELFT> &PltSec, - const GotSection<ELFT> &GotSec, - const OutputSection<ELFT> &BssSec, - StringRef Name, uint32_t sh_type, +OutputSection<ELFT>::OutputSection(StringRef Name, uint32_t sh_type, uintX_t sh_flags) - : OutputSectionBase<ELFT::Is64Bits>(Name, sh_type, sh_flags), - PltSec(PltSec), GotSec(GotSec), BssSec(BssSec) {} + : OutputSectionBase<ELFT::Is64Bits>(Name, sh_type, sh_flags) {} template <class ELFT> void OutputSection<ELFT>::addSection(InputSection<ELFT> *C) { @@ -404,8 +434,7 @@ void OutputSection<ELFT>::addSection(InputSection<ELFT> *C) { } template <class ELFT> -typename ELFFile<ELFT>::uintX_t -lld::elf2::getSymVA(const SymbolBody &S, const OutputSection<ELFT> &BssSec) { +typename ELFFile<ELFT>::uintX_t lld::elf2::getSymVA(const SymbolBody &S) { switch (S.kind()) { case SymbolBody::DefinedSyntheticKind: { auto &D = cast<DefinedSynthetic<ELFT>>(S); @@ -420,7 +449,7 @@ lld::elf2::getSymVA(const SymbolBody &S, const OutputSection<ELFT> &BssSec) { return OS->getVA() + SC->getOutputSectionOff() + DR.Sym.st_value; } case SymbolBody::DefinedCommonKind: - return BssSec.getVA() + cast<DefinedCommon<ELFT>>(S).OffsetInBSS; + return Out<ELFT>::Bss->getVA() + cast<DefinedCommon<ELFT>>(S).OffsetInBSS; case SymbolBody::SharedKind: case SymbolBody::UndefinedKind: return 0; @@ -460,7 +489,7 @@ bool lld::elf2::canBePreempted(const SymbolBody *Body) { template <class ELFT> void OutputSection<ELFT>::writeTo(uint8_t *Buf) { for (InputSection<ELFT> *C : Sections) - C->writeTo(Buf, BssSec, PltSec, GotSec); + C->writeTo(Buf); } template <bool Is64Bits> @@ -515,13 +544,12 @@ bool lld::elf2::shouldKeepInSymtab(StringRef SymName, template <class ELFT> SymbolTableSection<ELFT>::SymbolTableSection( - SymbolTable &Table, StringTableSection<ELFT::Is64Bits> &StrTabSec, - const OutputSection<ELFT> &BssSec) + SymbolTable &Table, StringTableSection<ELFT::Is64Bits> &StrTabSec) : OutputSectionBase<ELFT::Is64Bits>( StrTabSec.isDynamic() ? ".dynsym" : ".symtab", StrTabSec.isDynamic() ? llvm::ELF::SHT_DYNSYM : llvm::ELF::SHT_SYMTAB, StrTabSec.isDynamic() ? (uintX_t)llvm::ELF::SHF_ALLOC : 0), - Table(Table), StrTabSec(StrTabSec), BssSec(BssSec) { + Table(Table), StrTabSec(StrTabSec) { typedef OutputSectionBase<ELFT::Is64Bits> Base; typename Base::HeaderT &Header = this->Header; @@ -619,7 +647,7 @@ void SymbolTableSection<ELFT>::writeGlobalSymbols(uint8_t *&Buf) { Section = &cast<DefinedRegular<ELFT>>(Body)->Section; break; case SymbolBody::DefinedCommonKind: - OutSec = &BssSec; + OutSec = Out<ELFT>::Bss; break; case SymbolBody::UndefinedKind: case SymbolBody::DefinedAbsoluteKind: @@ -645,7 +673,7 @@ void SymbolTableSection<ELFT>::writeGlobalSymbols(uint8_t *&Buf) { ESym->setBindingAndType(Binding, Type); ESym->st_size = Size; ESym->setVisibility(Visibility); - ESym->st_value = getSymVA(*Body, BssSec); + ESym->st_value = getSymVA<ELFT>(*Body); if (Section) OutSec = Section->getOutputSection(); @@ -718,14 +746,10 @@ template class SymbolTableSection<ELF32BE>; template class SymbolTableSection<ELF64LE>; template class SymbolTableSection<ELF64BE>; -template ELFFile<ELF32LE>::uintX_t getSymVA(const SymbolBody &, - const OutputSection<ELF32LE> &); -template ELFFile<ELF32BE>::uintX_t getSymVA(const SymbolBody &, - const OutputSection<ELF32BE> &); -template ELFFile<ELF64LE>::uintX_t getSymVA(const SymbolBody &, - const OutputSection<ELF64LE> &); -template ELFFile<ELF64BE>::uintX_t getSymVA(const SymbolBody &, - const OutputSection<ELF64BE> &); +template ELFFile<ELF32LE>::uintX_t getSymVA<ELF32LE>(const SymbolBody &); +template ELFFile<ELF32BE>::uintX_t getSymVA<ELF32BE>(const SymbolBody &); +template ELFFile<ELF64LE>::uintX_t getSymVA<ELF64LE>(const SymbolBody &); +template ELFFile<ELF64BE>::uintX_t getSymVA<ELF64BE>(const SymbolBody &); template ELFFile<ELF32LE>::uintX_t getLocalSymVA(const ELFFile<ELF32LE>::Elf_Sym *, const ObjectFile<ELF32LE> &); diff --git a/lld/ELF/OutputSections.h b/lld/ELF/OutputSections.h index daeed4c670f..58e12f82717 100644 --- a/lld/ELF/OutputSections.h +++ b/lld/ELF/OutputSections.h @@ -33,8 +33,7 @@ template <class ELFT> class DefinedRegular; template <class ELFT> class ELFSymbolBody; template <class ELFT> -typename llvm::object::ELFFile<ELFT>::uintX_t -getSymVA(const SymbolBody &S, const OutputSection<ELFT> &BssSec); +typename llvm::object::ELFFile<ELFT>::uintX_t getSymVA(const SymbolBody &S); template <class ELFT> typename llvm::object::ELFFile<ELFT>::uintX_t @@ -103,7 +102,7 @@ class GotSection final : public OutputSectionBase<ELFT::Is64Bits> { typedef typename Base::uintX_t uintX_t; public: - GotSection(const OutputSection<ELFT> &BssSec); + GotSection(); void finalize() override { this->Header.sh_size = Entries.size() * this->getAddrSize(); } @@ -114,7 +113,6 @@ public: private: std::vector<const SymbolBody *> Entries; - const OutputSection<ELFT> &BssSec; }; template <class ELFT> @@ -123,7 +121,7 @@ class PltSection final : public OutputSectionBase<ELFT::Is64Bits> { typedef typename Base::uintX_t uintX_t; public: - PltSection(const GotSection<ELFT> &GotSec); + PltSection(); void finalize() override { this->Header.sh_size = Entries.size() * EntrySize; } @@ -135,7 +133,6 @@ public: private: std::vector<const SymbolBody *> Entries; - const GotSection<ELFT> &GotSec; }; template <class ELFT> struct DynamicReloc { @@ -152,8 +149,7 @@ public: typedef typename llvm::object::ELFFile<ELFT>::Elf_Sym_Range Elf_Sym_Range; typedef typename OutputSectionBase<ELFT::Is64Bits>::uintX_t uintX_t; SymbolTableSection(SymbolTable &Table, - StringTableSection<ELFT::Is64Bits> &StrTabSec, - const OutputSection<ELFT> &BssSec); + StringTableSection<ELFT::Is64Bits> &StrTabSec); void finalize() override; void writeTo(uint8_t *Buf) override; @@ -170,7 +166,6 @@ private: StringTableSection<ELFT::Is64Bits> &StrTabSec; unsigned NumVisible = 0; unsigned NumLocals = 0; - const OutputSection<ELFT> &BssSec; }; template <class ELFT> @@ -180,9 +175,7 @@ class RelocationSection final : public OutputSectionBase<ELFT::Is64Bits> { typedef typename llvm::object::ELFFile<ELFT>::uintX_t uintX_t; public: - RelocationSection(SymbolTableSection<ELFT> &DynSymSec, - const GotSection<ELFT> &GotSec, - const OutputSection<ELFT> &BssSec, bool IsRela); + RelocationSection(bool IsRela); void addReloc(const DynamicReloc<ELFT> &Reloc) { Relocs.push_back(Reloc); } void finalize() override; void writeTo(uint8_t *Buf) override; @@ -191,9 +184,6 @@ public: private: std::vector<DynamicReloc<ELFT>> Relocs; - SymbolTableSection<ELFT> &DynSymSec; - const GotSection<ELFT> &GotSec; - const OutputSection<ELFT> &BssSec; const bool IsRela; }; @@ -205,17 +195,12 @@ public: typedef typename llvm::object::ELFFile<ELFT>::Elf_Sym Elf_Sym; typedef typename llvm::object::ELFFile<ELFT>::Elf_Rel Elf_Rel; typedef typename llvm::object::ELFFile<ELFT>::Elf_Rela Elf_Rela; - OutputSection(const PltSection<ELFT> &PltSec, const GotSection<ELFT> &GotSec, - const OutputSection<ELFT> &BssSec, StringRef Name, - uint32_t sh_type, uintX_t sh_flags); + OutputSection(StringRef Name, uint32_t sh_type, uintX_t sh_flags); void addSection(InputSection<ELFT> *C); void writeTo(uint8_t *Buf) override; private: std::vector<InputSection<ELFT> *> Sections; - const PltSection<ELFT> &PltSec; - const GotSection<ELFT> &GotSec; - const OutputSection<ELFT> &BssSec; }; template <bool Is64Bits> @@ -253,11 +238,10 @@ class HashTableSection final : public OutputSectionBase<ELFT::Is64Bits> { typedef typename llvm::object::ELFFile<ELFT>::Elf_Word Elf_Word; public: - HashTableSection(SymbolTableSection<ELFT> &DynSymSec); + HashTableSection(); void addSymbol(SymbolBody *S); void finalize() override; void writeTo(uint8_t *Buf) override; - SymbolTableSection<ELFT> &getDynSymSec() { return DynSymSec; } private: uint32_t hash(StringRef Name) { @@ -271,7 +255,6 @@ private: } return H; } - SymbolTableSection<ELFT> &DynSymSec; std::vector<uint32_t> Hashes; }; @@ -285,9 +268,7 @@ class DynamicSection final : public OutputSectionBase<ELFT::Is64Bits> { typedef typename llvm::object::ELFFile<ELFT>::Elf_Dyn Elf_Dyn; public: - DynamicSection(SymbolTable &SymTab, HashTableSection<ELFT> &HashSec, - RelocationSection<ELFT> &RelaDynSec, - const OutputSection<ELFT> &BssSec); + DynamicSection(SymbolTable &SymTab); void finalize() override; void writeTo(uint8_t *Buf) override; @@ -296,15 +277,27 @@ public: OutputSection<ELFT> *FiniArraySec = nullptr; private: - HashTableSection<ELFT> &HashSec; - SymbolTableSection<ELFT> &DynSymSec; - StringTableSection<ELFT::Is64Bits> &DynStrSec; - RelocationSection<ELFT> &RelaDynSec; - const OutputSection<ELFT> &BssSec; SymbolTable &SymTab; const ELFSymbolBody<ELFT> *InitSym = nullptr; const ELFSymbolBody<ELFT> *FiniSym = nullptr; }; + +// All output sections that are hadnled by the linker specially are +// globally accessible. Writer initializes them, so don't use them +// until Writer is initialized. +template <class ELFT> struct Out { + static DynamicSection<ELFT> *Dynamic; + static GotSection<ELFT> *Got; + static HashTableSection<ELFT> *HashTab; + static InterpSection<ELFT::Is64Bits> *Interp; + static OutputSection<ELFT> *Bss; + static PltSection<ELFT> *Plt; + static RelocationSection<ELFT> *RelaDyn; + static StringTableSection<ELFT::Is64Bits> *DynStrTab; + static StringTableSection<ELFT::Is64Bits> *StrTab; + static SymbolTableSection<ELFT> *DynSymTab; + static SymbolTableSection<ELFT> *SymTab; +}; } } #endif diff --git a/lld/ELF/Writer.cpp b/lld/ELF/Writer.cpp index 404bf257d28..7c842533f23 100644 --- a/lld/ELF/Writer.cpp +++ b/lld/ELF/Writer.cpp @@ -58,14 +58,14 @@ template <class ELFT> struct ProgramHeader { Header.p_paddr = VA; } - void setValuesFromSection(OutputSectionBase<ELFT::Is64Bits> &Sec) { - Header.p_flags = toPHDRFlags(Sec.getFlags()); - Header.p_offset = Sec.getFileOff(); - Header.p_vaddr = Sec.getVA(); + void setValuesFromSection(OutputSectionBase<ELFT::Is64Bits> *Sec) { + Header.p_flags = toPHDRFlags(Sec->getFlags()); + Header.p_offset = Sec->getFileOff(); + Header.p_vaddr = Sec->getVA(); Header.p_paddr = Header.p_vaddr; - Header.p_filesz = Sec.getSize(); + Header.p_filesz = Sec->getSize(); Header.p_memsz = Header.p_filesz; - Header.p_align = Sec.getAlign(); + Header.p_align = Sec->getAlign(); } Elf_Phdr Header; @@ -82,13 +82,6 @@ public: typedef typename ELFFile<ELFT>::Elf_Sym Elf_Sym; typedef typename ELFFile<ELFT>::Elf_Sym_Range Elf_Sym_Range; typedef typename ELFFile<ELFT>::Elf_Rela Elf_Rela; - Writer(SymbolTable *T) - : SymTabSec(*T, StrTabSec, BssSec), DynSymSec(*T, DynStrSec, BssSec), - RelaDynSec(DynSymSec, GotSec, BssSec, T->shouldUseRela()), - GotSec(BssSec), PltSec(GotSec), HashSec(DynSymSec), - DynamicSec(*T, HashSec, RelaDynSec, BssSec), - BssSec(PltSec, GotSec, BssSec, ".bss", SHT_NOBITS, - SHF_ALLOC | SHF_WRITE) {} void run(); private: @@ -102,11 +95,12 @@ private: void writeHeader(); void writeSections(); bool needsInterpSection() const { - return !SymTabSec.getSymTable().getSharedFiles().empty() && + return !Out<ELFT>::SymTab->getSymTable().getSharedFiles().empty() && !Config->DynamicLinker.empty(); } bool isOutputDynamic() const { - return !SymTabSec.getSymTable().getSharedFiles().empty() || Config->Shared; + return !Out<ELFT>::SymTab->getSymTable().getSharedFiles().empty() || + Config->Shared; } bool needsDynamicSections() const { return isOutputDynamic(); } unsigned getVAStart() const { return Config->Shared ? 0 : VAStart; } @@ -126,41 +120,51 @@ private: uintX_t FileSize; uintX_t ProgramHeaderOff; uintX_t SectionHeaderOff; - - StringTableSection<ELFT::Is64Bits> StrTabSec = { /*dynamic=*/false }; - StringTableSection<ELFT::Is64Bits> DynStrSec = { /*dynamic=*/true }; - - lld::elf2::SymbolTableSection<ELFT> SymTabSec; - lld::elf2::SymbolTableSection<ELFT> DynSymSec; - - RelocationSection<ELFT> RelaDynSec; - - GotSection<ELFT> GotSec; - PltSection<ELFT> PltSec; - - HashTableSection<ELFT> HashSec; - - DynamicSection<ELFT> DynamicSec; - - InterpSection<ELFT::Is64Bits> InterpSec; - - OutputSection<ELFT> BssSec; }; } // anonymous namespace +template <class ELFT> static void doWriteResult(SymbolTable *Symtab) { + // Initialize output sections that are handled by Writer specially. + // Don't reorder because the order of initialization matters. + InterpSection<ELFT::Is64Bits> Interp; + Out<ELFT>::Interp = &Interp; + StringTableSection<ELFT::Is64Bits> StrTab(false); + Out<ELFT>::StrTab = &StrTab; + StringTableSection<ELFT::Is64Bits> DynStrTab(true); + Out<ELFT>::DynStrTab = &DynStrTab; + OutputSection<ELFT> Bss(".bss", SHT_NOBITS, SHF_ALLOC | SHF_WRITE); + Out<ELFT>::Bss = &Bss; + GotSection<ELFT> Got; + Out<ELFT>::Got = &Got; + PltSection<ELFT> Plt; + Out<ELFT>::Plt = &Plt; + SymbolTableSection<ELFT> SymTab(*Symtab, *Out<ELFT>::StrTab); + Out<ELFT>::SymTab = &SymTab; + SymbolTableSection<ELFT> DynSymTab(*Symtab, *Out<ELFT>::DynStrTab); + Out<ELFT>::DynSymTab = &DynSymTab; + HashTableSection<ELFT> HashTab; + Out<ELFT>::HashTab = &HashTab; + RelocationSection<ELFT> RelaDyn(Symtab->shouldUseRela()); + Out<ELFT>::RelaDyn = &RelaDyn; + DynamicSection<ELFT> Dynamic(*Symtab); + Out<ELFT>::Dynamic = &Dynamic; + + Writer<ELFT>().run(); +} + void lld::elf2::writeResult(SymbolTable *Symtab) { switch (Symtab->getFirstELF()->getELFKind()) { case ELF32LEKind: - Writer<object::ELF32LE>(Symtab).run(); + doWriteResult<object::ELF32LE>(Symtab); return; case ELF32BEKind: - Writer<object::ELF32BE>(Symtab).run(); + doWriteResult<object::ELF32BE>(Symtab); return; case ELF64LEKind: - Writer<object::ELF64LE>(Symtab).run(); + doWriteResult<object::ELF64LE>(Symtab); return; case ELF64BEKind: - Writer<object::ELF64BE>(Symtab).run(); + doWriteResult<object::ELF64BE>(Symtab); return; default: llvm_unreachable("Invalid kind"); @@ -229,19 +233,19 @@ void Writer<ELFT>::scanRelocs( if (Target->relocNeedsPlt(Type, *Body)) { if (Body->isInPlt()) continue; - PltSec.addEntry(Body); + Out<ELFT>::Plt->addEntry(Body); } if (Target->relocNeedsGot(Type, *Body)) { if (Body->isInGot()) continue; - GotSec.addEntry(Body); + Out<ELFT>::Got->addEntry(Body); } } if (canBePreempted(Body)) { Body->setUsedInDynamicReloc(); - RelaDynSec.addReloc({C, RI}); + Out<ELFT>::RelaDyn->addReloc({C, RI}); } else if (Config->Shared && !Target->isRelRelative(Type)) { - RelaDynSec.addReloc({C, RI}); + Out<ELFT>::RelaDyn->addReloc({C, RI}); } } } @@ -293,10 +297,11 @@ static void reportUndefined(const SymbolTable &S, const SymbolBody &Sym) { template <class ELFT> void Writer<ELFT>::createSections() { SmallDenseMap<SectionKey<ELFT::Is64Bits>, OutputSection<ELFT> *> Map; - OutputSections.push_back(&BssSec); - Map[{BssSec.getName(), BssSec.getType(), BssSec.getFlags()}] = &BssSec; + OutputSections.push_back(Out<ELFT>::Bss); + Map[{Out<ELFT>::Bss->getName(), Out<ELFT>::Bss->getType(), + Out<ELFT>::Bss->getFlags()}] = Out<ELFT>::Bss; - SymbolTable &Symtab = SymTabSec.getSymTable(); + SymbolTable &Symtab = Out<ELFT>::SymTab->getSymTable(); // Declare linker generated symbols. // This must be done before the relocation scan to make sure we can correctly @@ -321,7 +326,7 @@ template <class ELFT> void Writer<ELFT>::createSections() { for (const Elf_Sym &Sym : Syms) { ErrorOr<StringRef> SymName = Sym.getName(File.getStringTable()); if (SymName && shouldKeepInSymtab<ELFT>(*SymName, Sym)) - SymTabSec.addSymbol(*SymName, true); + Out<ELFT>::SymTab->addSymbol(*SymName, true); } } for (InputSection<ELFT> *C : File.getSections()) { @@ -332,8 +337,8 @@ template <class ELFT> void Writer<ELFT>::createSections() { H->sh_flags}; OutputSection<ELFT> *&Sec = Map[Key]; if (!Sec) { - Sec = new (CAlloc.Allocate()) OutputSection<ELFT>( - PltSec, GotSec, BssSec, Key.Name, Key.Type, Key.Flags); + Sec = new (CAlloc.Allocate()) + OutputSection<ELFT>(Key.Name, Key.Type, Key.Flags); OutputSections.push_back(Sec); } Sec->addSection(C); @@ -341,11 +346,11 @@ template <class ELFT> void Writer<ELFT>::createSections() { } } - DynamicSec.PreInitArraySec = + Out<ELFT>::Dynamic->PreInitArraySec = Map.lookup({".preinit_array", SHT_PREINIT_ARRAY, SHF_WRITE | SHF_ALLOC}); - DynamicSec.InitArraySec = + Out<ELFT>::Dynamic->InitArraySec = Map.lookup({".init_array", SHT_INIT_ARRAY, SHF_WRITE | SHF_ALLOC}); - DynamicSec.FiniArraySec = + Out<ELFT>::Dynamic->FiniArraySec = Map.lookup({".fini_array", SHT_FINI_ARRAY, SHF_WRITE | SHF_ALLOC}); auto AddStartEnd = [&Symtab](StringRef Start, StringRef End, @@ -357,11 +362,11 @@ template <class ELFT> void Writer<ELFT>::createSections() { }; AddStartEnd("__preinit_array_start", "__preinit_array_end", - DynamicSec.PreInitArraySec); + Out<ELFT>::Dynamic->PreInitArraySec); AddStartEnd("__init_array_start", "__init_array_end", - DynamicSec.InitArraySec); + Out<ELFT>::Dynamic->InitArraySec); AddStartEnd("__fini_array_start", "__fini_array_end", - DynamicSec.FiniArraySec); + Out<ELFT>::Dynamic->FiniArraySec); // FIXME: Try to avoid the extra walk over all global symbols. std::vector<DefinedCommon<ELFT> *> CommonSymbols; @@ -377,10 +382,10 @@ template <class ELFT> void Writer<ELFT>::createSections() { CommonSymbols.push_back(C); if (!includeInSymtab<ELFT>(*Body)) continue; - SymTabSec.addSymbol(Name); + Out<ELFT>::SymTab->addSymbol(Name); if (needsDynamicSections() && includeInDynamicSymtab(*Body)) - HashSec.addSymbol(Body); + Out<ELFT>::HashTab->addSymbol(Body); } // Sort the common symbols by alignment as an heuristic to pack them better. @@ -390,7 +395,7 @@ template <class ELFT> void Writer<ELFT>::createSections() { return A->MaxAlignment > B->MaxAlignment; }); - uintX_t Off = BssSec.getSize(); + uintX_t Off = Out<ELFT>::Bss->getSize(); for (DefinedCommon<ELFT> *C : CommonSymbols) { const Elf_Sym &Sym = C->Sym; uintX_t Align = C->MaxAlignment; @@ -399,24 +404,24 @@ template <class ELFT> void Writer<ELFT>::createSections() { Off += Sym.st_size; } - BssSec.setSize(Off); + Out<ELFT>::Bss->setSize(Off); - OutputSections.push_back(&SymTabSec); + OutputSections.push_back(Out<ELFT>::SymTab); if (needsDynamicSections()) { if (needsInterpSection()) - OutputSections.push_back(&InterpSec); - OutputSections.push_back(&DynSymSec); - OutputSections.push_back(&HashSec); - OutputSections.push_back(&DynamicSec); - OutputSections.push_back(&DynStrSec); - if (RelaDynSec.hasRelocs()) - OutputSections.push_back(&RelaDynSec); + OutputSections.push_back(Out<ELFT>::Interp); + OutputSections.push_back(Out<ELFT>::DynSymTab); + OutputSections.push_back(Out<ELFT>::HashTab); + OutputSections.push_back(Out<ELFT>::Dynamic); + OutputSections.push_back(Out<ELFT>::DynStrTab); + if (Out<ELFT>::RelaDyn->hasRelocs()) + OutputSections.push_back(Out<ELFT>::RelaDyn); } - if (!GotSec.empty()) - OutputSections.push_back(&GotSec); - if (!PltSec.empty()) - OutputSections.push_back(&PltSec); + if (!Out<ELFT>::Got->empty()) + OutputSections.push_back(Out<ELFT>::Got); + if (!Out<ELFT>::Plt->empty()) + OutputSections.push_back(Out<ELFT>::Plt); std::stable_sort( OutputSections.begin(), OutputSections.end(), @@ -462,13 +467,13 @@ template <class ELFT> void Writer<ELFT>::createSections() { // Always put StrTabSec last so that no section names are added to it after // it's finalized. - OutputSections.push_back(&StrTabSec); + OutputSections.push_back(Out<ELFT>::StrTab); for (unsigned I = 0, N = OutputSections.size(); I < N; ++I) OutputSections[I]->setSectionIndex(I + 1); - // Fill the DynStrSec early. - DynamicSec.finalize(); + // Fill the DynStrTab early. + Out<ELFT>::Dynamic->finalize(); } template <class ELFT> @@ -501,7 +506,7 @@ template <class ELFT> void Writer<ELFT>::assignAddresses() { FileHeaderPHDR.Header.p_align = PageSize; for (OutputSectionBase<ELFT::Is64Bits> *Sec : OutputSections) { - StrTabSec.add(Sec->getName()); + Out<ELFT>::StrTab->add(Sec->getName()); Sec->finalize(); if (Sec->getSize()) { @@ -562,7 +567,7 @@ template <class ELFT> void Writer<ELFT>::writeHeader() { : ELFDATA2MSB; EHdr->e_ident[EI_VERSION] = EV_CURRENT; - const SymbolTable &Symtab = SymTabSec.getSymTable(); + const SymbolTable &Symtab = Out<ELFT>::SymTab->getSymTable(); auto &FirstObj = cast<ObjectFile<ELFT>>(*Symtab.getFirstELF()); EHdr->e_ident[EI_OSABI] = FirstObj.getOSABI(); @@ -573,8 +578,7 @@ template <class ELFT> void Writer<ELFT>::writeHeader() { EHdr->e_machine = FirstObj.getEMachine(); EHdr->e_version = EV_CURRENT; SymbolBody *Entry = Symtab.getEntrySym(); - EHdr->e_entry = - Entry ? getSymVA(cast<ELFSymbolBody<ELFT>>(*Entry), BssSec) : 0; + EHdr->e_entry = Entry ? getSymVA<ELFT>(cast<ELFSymbolBody<ELFT>>(*Entry)) : 0; EHdr->e_phoff = ProgramHeaderOff; EHdr->e_shoff = SectionHeaderOff; EHdr->e_ehsize = sizeof(Elf_Ehdr); @@ -582,7 +586,7 @@ template <class ELFT> void Writer<ELFT>::writeHeader() { EHdr->e_phnum = PHDRs.size(); EHdr->e_shentsize = sizeof(Elf_Shdr); EHdr->e_shnum = getNumSections(); - EHdr->e_shstrndx = StrTabSec.getSectionIndex(); + EHdr->e_shstrndx = Out<ELFT>::StrTab->getSectionIndex(); // If nothing was merged into the file header PT_LOAD, set the size correctly. if (FileHeaderPHDR.Header.p_filesz == PageSize) { @@ -592,9 +596,9 @@ template <class ELFT> void Writer<ELFT>::writeHeader() { } if (needsInterpSection()) - InterpPHDR.setValuesFromSection(InterpSec); + InterpPHDR.setValuesFromSection(Out<ELFT>::Interp); if (needsDynamicSections()) - DynamicPHDR.setValuesFromSection(DynamicSec); + DynamicPHDR.setValuesFromSection(Out<ELFT>::Dynamic); auto PHdrs = reinterpret_cast<Elf_Phdr *>(Buf + EHdr->e_phoff); for (ProgramHeader<ELFT> *PHDR : PHDRs) @@ -604,7 +608,7 @@ template <class ELFT> void Writer<ELFT>::writeHeader() { // First entry is null. ++SHdrs; for (OutputSectionBase<ELFT::Is64Bits> *Sec : OutputSections) { - Sec->setNameOffset(StrTabSec.getFileOff(Sec->getName())); + Sec->setNameOffset(Out<ELFT>::StrTab->getFileOff(Sec->getName())); Sec->template writeHeaderTo<ELFT::TargetEndianness>(SHdrs++); } } |

