Index: lld/trunk/ELF/OutputSections.h =================================================================== --- lld/trunk/ELF/OutputSections.h +++ lld/trunk/ELF/OutputSections.h @@ -45,7 +45,6 @@ public: enum Kind { Base, - Dynamic, EHFrame, EHFrameHdr, GnuHashTable, @@ -478,55 +477,6 @@ unsigned Shift2; }; -template class DynamicSection final : public OutputSectionBase { - typedef typename ELFT::Dyn Elf_Dyn; - typedef typename ELFT::Rel Elf_Rel; - typedef typename ELFT::Rela Elf_Rela; - typedef typename ELFT::Shdr Elf_Shdr; - typedef typename ELFT::Sym Elf_Sym; - typedef typename ELFT::uint uintX_t; - - // The .dynamic section contains information for the dynamic linker. - // The section consists of fixed size entries, which consist of - // type and value fields. Value are one of plain integers, symbol - // addresses, or section addresses. This struct represents the entry. - struct Entry { - int32_t Tag; - union { - OutputSectionBase *OutSec; - InputSection *InSec; - uint64_t Val; - const SymbolBody *Sym; - }; - enum KindT { SecAddr, SecSize, SymAddr, PlainInt, InSecAddr } Kind; - Entry(int32_t Tag, OutputSectionBase *OutSec, KindT Kind = SecAddr) - : Tag(Tag), OutSec(OutSec), Kind(Kind) {} - Entry(int32_t Tag, InputSection *Sec) - : Tag(Tag), InSec(Sec), Kind(InSecAddr) {} - Entry(int32_t Tag, uint64_t Val) : Tag(Tag), Val(Val), Kind(PlainInt) {} - Entry(int32_t Tag, const SymbolBody *Sym) - : Tag(Tag), Sym(Sym), Kind(SymAddr) {} - }; - - // finalize() fills this vector with the section contents. finalize() - // cannot directly create final section contents because when the - // function is called, symbol or section addresses are not fixed yet. - std::vector Entries; - -public: - DynamicSection(); - void finalize() override; - void writeTo(uint8_t *Buf) override; - Kind getKind() const override { return Dynamic; } - static bool classof(const OutputSectionBase *B) { - return B->getKind() == Dynamic; - } - -private: - void addEntries(); - void Add(Entry E) { Entries.push_back(E); } -}; - // --eh-frame-hdr option tells linker to construct a header for all the // .eh_frame sections. This header is placed to a section named .eh_frame_hdr // and also to a PT_GNU_EH_FRAME segment. @@ -566,7 +516,6 @@ typedef typename ELFT::Phdr Elf_Phdr; static uint8_t First; - static DynamicSection *Dynamic; static EhFrameHeader *EhFrameHdr; static EhOutputSection *EhFrame; static GdbIndexSection *GdbIndex; @@ -627,7 +576,6 @@ } template uint8_t Out::First; -template DynamicSection *Out::Dynamic; template EhFrameHeader *Out::EhFrameHdr; template EhOutputSection *Out::EhFrame; template GdbIndexSection *Out::GdbIndex; Index: lld/trunk/ELF/OutputSections.cpp =================================================================== --- lld/trunk/ELF/OutputSections.cpp +++ lld/trunk/ELF/OutputSections.cpp @@ -395,177 +395,6 @@ static unsigned getVerDefNum() { return Config->VersionDefinitions.size() + 1; } template -DynamicSection::DynamicSection() - : OutputSectionBase(".dynamic", SHT_DYNAMIC, SHF_ALLOC | SHF_WRITE) { - this->Addralign = sizeof(uintX_t); - this->Entsize = ELFT::Is64Bits ? 16 : 8; - - // .dynamic section is not writable on MIPS. - // See "Special Section" in Chapter 4 in the following document: - // ftp://www.linux-mips.org/pub/linux/mips/doc/ABI/mipsabi.pdf - if (Config->EMachine == EM_MIPS) - this->Flags = SHF_ALLOC; - - addEntries(); -} - -// There are some dynamic entries that don't depend on other sections. -// Such entries can be set early. -template void DynamicSection::addEntries() { - // Add strings to .dynstr early so that .dynstr's size will be - // fixed early. - for (StringRef S : Config->AuxiliaryList) - Add({DT_AUXILIARY, In::DynStrTab->addString(S)}); - if (!Config->RPath.empty()) - Add({Config->EnableNewDtags ? DT_RUNPATH : DT_RPATH, - In::DynStrTab->addString(Config->RPath)}); - for (SharedFile *F : Symtab::X->getSharedFiles()) - if (F->isNeeded()) - Add({DT_NEEDED, In::DynStrTab->addString(F->getSoName())}); - if (!Config->SoName.empty()) - Add({DT_SONAME, In::DynStrTab->addString(Config->SoName)}); - - // Set DT_FLAGS and DT_FLAGS_1. - uint32_t DtFlags = 0; - uint32_t DtFlags1 = 0; - if (Config->Bsymbolic) - DtFlags |= DF_SYMBOLIC; - if (Config->ZNodelete) - DtFlags1 |= DF_1_NODELETE; - if (Config->ZNow) { - DtFlags |= DF_BIND_NOW; - DtFlags1 |= DF_1_NOW; - } - if (Config->ZOrigin) { - DtFlags |= DF_ORIGIN; - DtFlags1 |= DF_1_ORIGIN; - } - - if (DtFlags) - Add({DT_FLAGS, DtFlags}); - if (DtFlags1) - Add({DT_FLAGS_1, DtFlags1}); - - if (!Config->Entry.empty()) - Add({DT_DEBUG, (uint64_t)0}); -} - -// Add remaining entries to complete .dynamic contents. -template void DynamicSection::finalize() { - if (this->Size) - return; // Already finalized. - - this->Link = In::DynStrTab->OutSec->SectionIndex; - - if (Out::RelaDyn->hasRelocs()) { - bool IsRela = Config->Rela; - Add({IsRela ? DT_RELA : DT_REL, Out::RelaDyn}); - Add({IsRela ? DT_RELASZ : DT_RELSZ, Out::RelaDyn->Size}); - Add({IsRela ? DT_RELAENT : DT_RELENT, - uintX_t(IsRela ? sizeof(Elf_Rela) : sizeof(Elf_Rel))}); - - // MIPS dynamic loader does not support RELCOUNT tag. - // The problem is in the tight relation between dynamic - // relocations and GOT. So do not emit this tag on MIPS. - if (Config->EMachine != EM_MIPS) { - size_t NumRelativeRels = Out::RelaDyn->getRelativeRelocCount(); - if (Config->ZCombreloc && NumRelativeRels) - Add({IsRela ? DT_RELACOUNT : DT_RELCOUNT, NumRelativeRels}); - } - } - if (Out::RelaPlt && Out::RelaPlt->hasRelocs()) { - Add({DT_JMPREL, Out::RelaPlt}); - Add({DT_PLTRELSZ, Out::RelaPlt->Size}); - Add({Config->EMachine == EM_MIPS ? DT_MIPS_PLTGOT : DT_PLTGOT, - In::GotPlt}); - Add({DT_PLTREL, uint64_t(Config->Rela ? DT_RELA : DT_REL)}); - } - - Add({DT_SYMTAB, Out::DynSymTab}); - Add({DT_SYMENT, sizeof(Elf_Sym)}); - Add({DT_STRTAB, In::DynStrTab}); - Add({DT_STRSZ, In::DynStrTab->getSize()}); - if (Out::GnuHashTab) - Add({DT_GNU_HASH, Out::GnuHashTab}); - if (Out::HashTab) - Add({DT_HASH, Out::HashTab}); - - if (Out::PreinitArray) { - Add({DT_PREINIT_ARRAY, Out::PreinitArray}); - Add({DT_PREINIT_ARRAYSZ, Out::PreinitArray, Entry::SecSize}); - } - if (Out::InitArray) { - Add({DT_INIT_ARRAY, Out::InitArray}); - Add({DT_INIT_ARRAYSZ, Out::InitArray, Entry::SecSize}); - } - if (Out::FiniArray) { - Add({DT_FINI_ARRAY, Out::FiniArray}); - Add({DT_FINI_ARRAYSZ, Out::FiniArray, Entry::SecSize}); - } - - if (SymbolBody *B = Symtab::X->find(Config->Init)) - Add({DT_INIT, B}); - if (SymbolBody *B = Symtab::X->find(Config->Fini)) - Add({DT_FINI, B}); - - bool HasVerNeed = Out::VerNeed->getNeedNum() != 0; - if (HasVerNeed || Out::VerDef) - Add({DT_VERSYM, Out::VerSym}); - if (Out::VerDef) { - Add({DT_VERDEF, Out::VerDef}); - Add({DT_VERDEFNUM, getVerDefNum()}); - } - if (HasVerNeed) { - Add({DT_VERNEED, Out::VerNeed}); - Add({DT_VERNEEDNUM, Out::VerNeed->getNeedNum()}); - } - - if (Config->EMachine == EM_MIPS) { - Add({DT_MIPS_RLD_VERSION, 1}); - Add({DT_MIPS_FLAGS, RHF_NOTPOT}); - Add({DT_MIPS_BASE_ADDRESS, Config->ImageBase}); - Add({DT_MIPS_SYMTABNO, Out::DynSymTab->getNumSymbols()}); - Add({DT_MIPS_LOCAL_GOTNO, In::Got->getMipsLocalEntriesNum()}); - if (const SymbolBody *B = In::Got->getMipsFirstGlobalEntry()) - Add({DT_MIPS_GOTSYM, B->DynsymIndex}); - else - Add({DT_MIPS_GOTSYM, Out::DynSymTab->getNumSymbols()}); - Add({DT_PLTGOT, In::Got}); - if (Out::MipsRldMap) - Add({DT_MIPS_RLD_MAP, Out::MipsRldMap}); - } - - // +1 for DT_NULL - this->Size = (Entries.size() + 1) * this->Entsize; -} - -template void DynamicSection::writeTo(uint8_t *Buf) { - auto *P = reinterpret_cast(Buf); - - for (const Entry &E : Entries) { - P->d_tag = E.Tag; - switch (E.Kind) { - case Entry::SecAddr: - P->d_un.d_ptr = E.OutSec->Addr; - break; - case Entry::InSecAddr: - P->d_un.d_ptr = E.InSec->OutSec->Addr + E.InSec->OutSecOff; - break; - case Entry::SecSize: - P->d_un.d_val = E.OutSec->Size; - break; - case Entry::SymAddr: - P->d_un.d_ptr = E.Sym->template getVA(); - break; - case Entry::PlainInt: - P->d_un.d_val = E.Val; - break; - } - ++P; - } -} - -template EhFrameHeader::EhFrameHeader() : OutputSectionBase(".eh_frame_hdr", SHT_PROGBITS, SHF_ALLOC) {} @@ -650,14 +479,6 @@ } } - // Recalculate input section offsets if we own any synthetic section - for (auto *SS : In::SyntheticSections) - if (SS && this == SS->OutSec) { - this->Size = 0; - assignOffsets(); - break; - } - if (Type != SHT_RELA && Type != SHT_REL) return; this->Link = Out::SymTab->SectionIndex; @@ -1544,11 +1365,6 @@ template class HashTableSection; template class HashTableSection; -template class DynamicSection; -template class DynamicSection; -template class DynamicSection; -template class DynamicSection; - template class OutputSection; template class OutputSection; template class OutputSection; Index: lld/trunk/ELF/SyntheticSections.h =================================================================== --- lld/trunk/ELF/SyntheticSections.h +++ lld/trunk/ELF/SyntheticSections.h @@ -72,6 +72,7 @@ virtual void writeTo(uint8_t *Buf) = 0; virtual size_t getSize() const { return this->Data.size(); } + virtual void finalize() {} uintX_t getVA() const { return this->OutSec ? this->OutSec->Addr + this->OutSecOff : 0; } @@ -144,7 +145,7 @@ GotSection(); void writeTo(uint8_t *Buf) override; size_t getSize() const override { return Size; } - void finalize(); + void finalize() override; void addEntry(SymbolBody &Sym); void addMipsEntry(SymbolBody &Sym, uintX_t Addend, RelExpr Expr); bool addDynTlsEntry(SymbolBody &Sym); @@ -238,6 +239,54 @@ std::vector Strings; }; +template +class DynamicSection final : public SyntheticSection { + typedef typename ELFT::Dyn Elf_Dyn; + typedef typename ELFT::Rel Elf_Rel; + typedef typename ELFT::Rela Elf_Rela; + typedef typename ELFT::Shdr Elf_Shdr; + typedef typename ELFT::Sym Elf_Sym; + typedef typename ELFT::uint uintX_t; + + // The .dynamic section contains information for the dynamic linker. + // The section consists of fixed size entries, which consist of + // type and value fields. Value are one of plain integers, symbol + // addresses, or section addresses. This struct represents the entry. + struct Entry { + int32_t Tag; + union { + OutputSectionBase *OutSec; + InputSection *InSec; + uint64_t Val; + const SymbolBody *Sym; + }; + enum KindT { SecAddr, SecSize, SymAddr, PlainInt, InSecAddr } Kind; + Entry(int32_t Tag, OutputSectionBase *OutSec, KindT Kind = SecAddr) + : Tag(Tag), OutSec(OutSec), Kind(Kind) {} + Entry(int32_t Tag, InputSection *Sec) + : Tag(Tag), InSec(Sec), Kind(InSecAddr) {} + Entry(int32_t Tag, uint64_t Val) : Tag(Tag), Val(Val), Kind(PlainInt) {} + Entry(int32_t Tag, const SymbolBody *Sym) + : Tag(Tag), Sym(Sym), Kind(SymAddr) {} + }; + + // finalize() fills this vector with the section contents. finalize() + // cannot directly create final section contents because when the + // function is called, symbol or section addresses are not fixed yet. + std::vector Entries; + +public: + DynamicSection(); + void finalize() override; + void writeTo(uint8_t *Buf) override; + size_t getSize() const override { return Size; } + +private: + void addEntries(); + void Add(Entry E) { Entries.push_back(E); } + uintX_t Size = 0; +}; + template InputSection *createCommonSection(); template InputSection *createInterpSection(); template MergeInputSection *createCommentSection(); @@ -246,6 +295,7 @@ template struct In { static BuildIdSection *BuildId; static InputSection *Common; + static DynamicSection *Dynamic; static StringTableSection *DynStrTab; static GotSection *Got; static GotPltSection *GotPlt; @@ -255,15 +305,11 @@ static MipsReginfoSection *MipsReginfo; static StringTableSection *ShStrTab; static StringTableSection *StrTab; - - // Contains list of sections, which size is not known when - // createSections() is called. This list is used when output - // sections are being finalized to calculate their size correctly. - static std::vector *> SyntheticSections; }; template BuildIdSection *In::BuildId; template InputSection *In::Common; +template DynamicSection *In::Dynamic; template StringTableSection *In::DynStrTab; template GotSection *In::Got; template GotPltSection *In::GotPlt; @@ -273,9 +319,6 @@ template MipsReginfoSection *In::MipsReginfo; template StringTableSection *In::ShStrTab; template StringTableSection *In::StrTab; -template -std::vector *> In::SyntheticSections; - } // namespace elf } // namespace lld Index: lld/trunk/ELF/SyntheticSections.cpp =================================================================== --- lld/trunk/ELF/SyntheticSections.cpp +++ lld/trunk/ELF/SyntheticSections.cpp @@ -673,6 +673,181 @@ } } +static unsigned getVerDefNum() { return Config->VersionDefinitions.size() + 1; } + +template +DynamicSection::DynamicSection() + : SyntheticSection(SHF_ALLOC | SHF_WRITE, SHT_DYNAMIC, + sizeof(uintX_t), ".dynamic") { + this->Entsize = ELFT::Is64Bits ? 16 : 8; + // .dynamic section is not writable on MIPS. + // See "Special Section" in Chapter 4 in the following document: + // ftp://www.linux-mips.org/pub/linux/mips/doc/ABI/mipsabi.pdf + if (Config->EMachine == EM_MIPS) + this->Flags = SHF_ALLOC; + + addEntries(); +} + +// There are some dynamic entries that don't depend on other sections. +// Such entries can be set early. +template void DynamicSection::addEntries() { + // Add strings to .dynstr early so that .dynstr's size will be + // fixed early. + for (StringRef S : Config->AuxiliaryList) + Add({DT_AUXILIARY, In::DynStrTab->addString(S)}); + if (!Config->RPath.empty()) + Add({Config->EnableNewDtags ? DT_RUNPATH : DT_RPATH, + In::DynStrTab->addString(Config->RPath)}); + for (SharedFile *F : Symtab::X->getSharedFiles()) + if (F->isNeeded()) + Add({DT_NEEDED, In::DynStrTab->addString(F->getSoName())}); + if (!Config->SoName.empty()) + Add({DT_SONAME, In::DynStrTab->addString(Config->SoName)}); + + // Set DT_FLAGS and DT_FLAGS_1. + uint32_t DtFlags = 0; + uint32_t DtFlags1 = 0; + if (Config->Bsymbolic) + DtFlags |= DF_SYMBOLIC; + if (Config->ZNodelete) + DtFlags1 |= DF_1_NODELETE; + if (Config->ZNow) { + DtFlags |= DF_BIND_NOW; + DtFlags1 |= DF_1_NOW; + } + if (Config->ZOrigin) { + DtFlags |= DF_ORIGIN; + DtFlags1 |= DF_1_ORIGIN; + } + + if (DtFlags) + Add({DT_FLAGS, DtFlags}); + if (DtFlags1) + Add({DT_FLAGS_1, DtFlags1}); + + if (!Config->Entry.empty()) + Add({DT_DEBUG, (uint64_t)0}); +} + +// Add remaining entries to complete .dynamic contents. +template void DynamicSection::finalize() { + if (this->Size) + return; // Already finalized. + + this->Link = In::DynStrTab->OutSec->SectionIndex; + + if (Out::RelaDyn->hasRelocs()) { + bool IsRela = Config->Rela; + Add({IsRela ? DT_RELA : DT_REL, Out::RelaDyn}); + Add({IsRela ? DT_RELASZ : DT_RELSZ, Out::RelaDyn->Size}); + Add({IsRela ? DT_RELAENT : DT_RELENT, + uintX_t(IsRela ? sizeof(Elf_Rela) : sizeof(Elf_Rel))}); + + // MIPS dynamic loader does not support RELCOUNT tag. + // The problem is in the tight relation between dynamic + // relocations and GOT. So do not emit this tag on MIPS. + if (Config->EMachine != EM_MIPS) { + size_t NumRelativeRels = Out::RelaDyn->getRelativeRelocCount(); + if (Config->ZCombreloc && NumRelativeRels) + Add({IsRela ? DT_RELACOUNT : DT_RELCOUNT, NumRelativeRels}); + } + } + if (Out::RelaPlt && Out::RelaPlt->hasRelocs()) { + Add({DT_JMPREL, Out::RelaPlt}); + Add({DT_PLTRELSZ, Out::RelaPlt->Size}); + Add({Config->EMachine == EM_MIPS ? DT_MIPS_PLTGOT : DT_PLTGOT, + In::GotPlt}); + Add({DT_PLTREL, uint64_t(Config->Rela ? DT_RELA : DT_REL)}); + } + + Add({DT_SYMTAB, Out::DynSymTab}); + Add({DT_SYMENT, sizeof(Elf_Sym)}); + Add({DT_STRTAB, In::DynStrTab}); + Add({DT_STRSZ, In::DynStrTab->getSize()}); + if (Out::GnuHashTab) + Add({DT_GNU_HASH, Out::GnuHashTab}); + if (Out::HashTab) + Add({DT_HASH, Out::HashTab}); + + if (Out::PreinitArray) { + Add({DT_PREINIT_ARRAY, Out::PreinitArray}); + Add({DT_PREINIT_ARRAYSZ, Out::PreinitArray, Entry::SecSize}); + } + if (Out::InitArray) { + Add({DT_INIT_ARRAY, Out::InitArray}); + Add({DT_INIT_ARRAYSZ, Out::InitArray, Entry::SecSize}); + } + if (Out::FiniArray) { + Add({DT_FINI_ARRAY, Out::FiniArray}); + Add({DT_FINI_ARRAYSZ, Out::FiniArray, Entry::SecSize}); + } + + if (SymbolBody *B = Symtab::X->find(Config->Init)) + Add({DT_INIT, B}); + if (SymbolBody *B = Symtab::X->find(Config->Fini)) + Add({DT_FINI, B}); + + bool HasVerNeed = Out::VerNeed->getNeedNum() != 0; + if (HasVerNeed || Out::VerDef) + Add({DT_VERSYM, Out::VerSym}); + if (Out::VerDef) { + Add({DT_VERDEF, Out::VerDef}); + Add({DT_VERDEFNUM, getVerDefNum()}); + } + if (HasVerNeed) { + Add({DT_VERNEED, Out::VerNeed}); + Add({DT_VERNEEDNUM, Out::VerNeed->getNeedNum()}); + } + + if (Config->EMachine == EM_MIPS) { + Add({DT_MIPS_RLD_VERSION, 1}); + Add({DT_MIPS_FLAGS, RHF_NOTPOT}); + Add({DT_MIPS_BASE_ADDRESS, Config->ImageBase}); + Add({DT_MIPS_SYMTABNO, Out::DynSymTab->getNumSymbols()}); + Add({DT_MIPS_LOCAL_GOTNO, In::Got->getMipsLocalEntriesNum()}); + if (const SymbolBody *B = In::Got->getMipsFirstGlobalEntry()) + Add({DT_MIPS_GOTSYM, B->DynsymIndex}); + else + Add({DT_MIPS_GOTSYM, Out::DynSymTab->getNumSymbols()}); + Add({DT_PLTGOT, In::Got}); + if (Out::MipsRldMap) + Add({DT_MIPS_RLD_MAP, Out::MipsRldMap}); + } + + this->OutSec->Entsize = this->Entsize; + this->OutSec->Link = this->Link; + + // +1 for DT_NULL + this->Size = (Entries.size() + 1) * this->Entsize; +} + +template void DynamicSection::writeTo(uint8_t *Buf) { + auto *P = reinterpret_cast(Buf); + + for (const Entry &E : Entries) { + P->d_tag = E.Tag; + switch (E.Kind) { + case Entry::SecAddr: + P->d_un.d_ptr = E.OutSec->Addr; + break; + case Entry::InSecAddr: + P->d_un.d_ptr = E.InSec->OutSec->Addr + E.InSec->OutSecOff; + break; + case Entry::SecSize: + P->d_un.d_val = E.OutSec->Size; + break; + case Entry::SymAddr: + P->d_un.d_ptr = E.Sym->template getVA(); + break; + case Entry::PlainInt: + P->d_un.d_val = E.Val; + break; + } + ++P; + } +} + template InputSection *elf::createCommonSection(); template InputSection *elf::createCommonSection(); template InputSection *elf::createCommonSection(); @@ -747,3 +922,8 @@ template class elf::StringTableSection; template class elf::StringTableSection; template class elf::StringTableSection; + +template class elf::DynamicSection; +template class elf::DynamicSection; +template class elf::DynamicSection; +template class elf::DynamicSection; Index: lld/trunk/ELF/Target.cpp =================================================================== --- lld/trunk/ELF/Target.cpp +++ lld/trunk/ELF/Target.cpp @@ -356,7 +356,7 @@ } void X86TargetInfo::writeGotPltHeader(uint8_t *Buf) const { - write32le(Buf, Out::Dynamic->Addr); + write32le(Buf, In::Dynamic->getVA()); } void X86TargetInfo::writeGotPlt(uint8_t *Buf, const SymbolBody &S) const { @@ -596,7 +596,7 @@ // required, but it is documented in the psabi and the glibc dynamic linker // seems to use it (note that this is relevant for linking ld.so, not any // other program). - write64le(Buf, Out::Dynamic->Addr); + write64le(Buf, In::Dynamic->getVA()); } template Index: lld/trunk/ELF/Writer.cpp =================================================================== --- lld/trunk/ELF/Writer.cpp +++ lld/trunk/ELF/Writer.cpp @@ -210,7 +210,7 @@ Out::Bss = make>(".bss", SHT_NOBITS, SHF_ALLOC | SHF_WRITE); In::DynStrTab = make>(".dynstr", true); - Out::Dynamic = make>(); + In::Dynamic = make>(); Out::EhFrame = make>(); Out::Plt = make>(); Out::RelaDyn = make>( @@ -314,13 +314,6 @@ In::Got = make>(); In::GotPlt = make>(); - - // These sections are filled after createSections() is called. - // We use this list to fixup size of output sections, when they - // are finalized. - In::SyntheticSections = {In::ShStrTab, In::StrTab, - In::DynStrTab, In::Got, - In::GotPlt}; } template @@ -434,7 +427,7 @@ return true; if (Sec == In::GotPlt->OutSec) return Config->ZNow; - if (Sec == Out::Dynamic || Sec == In::Got->OutSec) + if (Sec == In::Dynamic->OutSec || Sec == In::Got->OutSec) return true; StringRef S = Sec->getName(); return S == ".data.rel.ro" || S == ".ctors" || S == ".dtors" || S == ".jcr" || @@ -861,6 +854,17 @@ Script::X->adjustSectionsAfterSorting(); } +template +static void +finalizeSynthetic(const std::vector *> &Sections) { + for (SyntheticSection *SS : Sections) + if (SS && SS->OutSec) { + SS->finalize(); + SS->OutSec->Size = 0; + SS->OutSec->assignOffsets(); + } +} + // Create output section objects and add them to OutputSections. template void Writer::finalizeSections() { Out::DebugInfo = findSection(".debug_info"); @@ -882,8 +886,7 @@ // Even the author of gold doesn't remember why gold behaves that way. // https://sourceware.org/ml/binutils/2002-03/msg00360.html if (Out::DynSymTab) - Symtab::X->addSynthetic("_DYNAMIC", Out::Dynamic, 0, - STV_HIDDEN); + addRegular("_DYNAMIC", In::Dynamic, 0); // Define __rel[a]_iplt_{start,end} symbols if needed. addRelIpltSymbols(); @@ -940,11 +943,11 @@ // at the end because some tags like RELSZ depend on result // of finalizing other sections. for (OutputSectionBase *Sec : OutputSections) - if (Sec != Out::Dynamic) - Sec->finalize(); + Sec->finalize(); - if (Out::DynSymTab) - Out::Dynamic->finalize(); + finalizeSynthetic({In::ShStrTab, In::StrTab, + In::DynStrTab, In::Got, In::GotPlt, + In::Dynamic}); // Now that all output offsets are fixed. Finalize mergeable sections // to fix their maps from input offsets to output offsets. @@ -992,7 +995,7 @@ Add(Out::GnuHashTab); Add(Out::HashTab); - Add(Out::Dynamic); + addInputSec(In::Dynamic); addInputSec(In::DynStrTab); if (Out::RelaDyn->hasRelocs()) Add(Out::RelaDyn); @@ -1006,10 +1009,8 @@ // We fill .got and .got.plt sections in scanRelocs(). This is the // reason we don't add it earlier in createSections(). - if (needsGot()) { - In::Got->finalize(); + if (needsGot()) addInputSec(In::Got); - } if (!In::GotPlt->empty()) addInputSec(In::GotPlt); @@ -1158,8 +1159,8 @@ // Add an entry for .dynamic. if (Out::DynSymTab) { - Phdr &H = *AddHdr(PT_DYNAMIC, Out::Dynamic->getPhdrFlags()); - H.add(Out::Dynamic); + Phdr &H = *AddHdr(PT_DYNAMIC, In::Dynamic->OutSec->getPhdrFlags()); + H.add(In::Dynamic->OutSec); } // PT_GNU_RELRO includes all sections that should be marked as