Index: lld/trunk/ELF/OutputSections.h =================================================================== --- lld/trunk/ELF/OutputSections.h +++ lld/trunk/ELF/OutputSections.h @@ -54,7 +54,6 @@ Plt, Regular, Reloc, - StrTable, SymTable, VersDef, VersNeed, @@ -424,26 +423,6 @@ llvm::DenseMap, SymbolBody *>, CieRecord> CieMap; }; -template -class StringTableSection final : public OutputSectionBase { - -public: - typedef typename ELFT::uint uintX_t; - StringTableSection(StringRef Name, bool Dynamic); - unsigned addString(StringRef S, bool HashIt = true); - void writeTo(uint8_t *Buf) override; - bool isDynamic() const { return Dynamic; } - Kind getKind() const override { return StrTable; } - static bool classof(const OutputSectionBase *B) { - return B->getKind() == StrTable; - } - -private: - const bool Dynamic; - llvm::DenseMap StringMap; - std::vector Strings; -}; - template class HashTableSection final : public OutputSectionBase { typedef typename ELFT::Word Elf_Word; @@ -600,9 +579,6 @@ static PltSection *Plt; static RelocationSection *RelaDyn; static RelocationSection *RelaPlt; - static StringTableSection *DynStrTab; - static StringTableSection *ShStrTab; - static StringTableSection *StrTab; static SymbolTableSection *DynSymTab; static SymbolTableSection *SymTab; static VersionDefinitionSection *VerDef; @@ -664,9 +640,6 @@ template PltSection *Out::Plt; template RelocationSection *Out::RelaDyn; template RelocationSection *Out::RelaPlt; -template StringTableSection *Out::DynStrTab; -template StringTableSection *Out::ShStrTab; -template StringTableSection *Out::StrTab; template SymbolTableSection *Out::DynSymTab; template SymbolTableSection *Out::SymTab; template VersionDefinitionSection *Out::VerDef; Index: lld/trunk/ELF/OutputSections.cpp =================================================================== --- lld/trunk/ELF/OutputSections.cpp +++ lld/trunk/ELF/OutputSections.cpp @@ -415,15 +415,15 @@ // Add strings to .dynstr early so that .dynstr's size will be // fixed early. for (StringRef S : Config->AuxiliaryList) - Add({DT_AUXILIARY, Out::DynStrTab->addString(S)}); + Add({DT_AUXILIARY, In::DynStrTab->addString(S)}); if (!Config->RPath.empty()) Add({Config->EnableNewDtags ? DT_RUNPATH : DT_RPATH, - Out::DynStrTab->addString(Config->RPath)}); + In::DynStrTab->addString(Config->RPath)}); for (SharedFile *F : Symtab::X->getSharedFiles()) if (F->isNeeded()) - Add({DT_NEEDED, Out::DynStrTab->addString(F->getSoName())}); + Add({DT_NEEDED, In::DynStrTab->addString(F->getSoName())}); if (!Config->SoName.empty()) - Add({DT_SONAME, Out::DynStrTab->addString(Config->SoName)}); + Add({DT_SONAME, In::DynStrTab->addString(Config->SoName)}); // Set DT_FLAGS and DT_FLAGS_1. uint32_t DtFlags = 0; @@ -455,7 +455,7 @@ if (this->Size) return; // Already finalized. - this->Link = Out::DynStrTab->SectionIndex; + this->Link = In::DynStrTab->OutSec->SectionIndex; if (Out::RelaDyn->hasRelocs()) { bool IsRela = Config->Rela; @@ -483,8 +483,8 @@ Add({DT_SYMTAB, Out::DynSymTab}); Add({DT_SYMENT, sizeof(Elf_Sym)}); - Add({DT_STRTAB, Out::DynStrTab}); - Add({DT_STRSZ, Out::DynStrTab->Size}); + Add({DT_STRTAB, In::DynStrTab}); + Add({DT_STRSZ, In::DynStrTab->getSize()}); if (Out::GnuHashTab) Add({DT_GNU_HASH, Out::GnuHashTab}); if (Out::HashTab) @@ -650,6 +650,15 @@ this->Link = D->OutSec->SectionIndex; } } + + // 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; @@ -1052,40 +1061,6 @@ } template -StringTableSection::StringTableSection(StringRef Name, bool Dynamic) - : OutputSectionBase(Name, SHT_STRTAB, Dynamic ? (uintX_t)SHF_ALLOC : 0), - Dynamic(Dynamic) { - // ELF string tables start with a NUL byte, so 1. - this->Size = 1; -} - -// Adds a string to the string table. If HashIt is true we hash and check for -// duplicates. It is optional because the name of global symbols are already -// uniqued and hashing them again has a big cost for a small value: uniquing -// them with some other string that happens to be the same. -template -unsigned StringTableSection::addString(StringRef S, bool HashIt) { - if (HashIt) { - auto R = StringMap.insert(std::make_pair(S, this->Size)); - if (!R.second) - return R.first->second; - } - unsigned Ret = this->Size; - this->Size = this->Size + S.size() + 1; - Strings.push_back(S); - return Ret; -} - -template void StringTableSection::writeTo(uint8_t *Buf) { - // ELF string tables start with NUL byte, so advance the pointer by one. - ++Buf; - for (StringRef S : Strings) { - memcpy(Buf, S.data(), S.size()); - Buf += S.size() + 1; - } -} - -template typename ELFT::uint DynamicReloc::getOffset() const { if (OutputSec) return OutputSec->Addr + OffsetInSec; @@ -1148,7 +1123,7 @@ return; // Already finalized. this->Size = getNumSymbols() * sizeof(Elf_Sym); - this->Link = StrTabSec.SectionIndex; + this->Link = StrTabSec.OutSec->SectionIndex; this->Info = NumLocals + 1; if (Config->Relocatable) { @@ -1300,12 +1275,12 @@ } template void VersionDefinitionSection::finalize() { - FileDefNameOff = Out::DynStrTab->addString(getFileDefName()); + FileDefNameOff = In::DynStrTab->addString(getFileDefName()); for (VersionDefinition &V : Config->VersionDefinitions) - V.NameOff = Out::DynStrTab->addString(V.Name); + V.NameOff = In::DynStrTab->addString(V.Name); this->Size = (sizeof(Elf_Verdef) + sizeof(Elf_Verdaux)) * getVerDefNum(); - this->Link = Out::DynStrTab->SectionIndex; + this->Link = In::DynStrTab->OutSec->SectionIndex; // sh_info should be set to the number of definitions. This fact is missed in // documentation, but confirmed by binutils community: @@ -1389,13 +1364,13 @@ // to create one by adding it to our needed list and creating a dynstr entry // for the soname. if (F->VerdefMap.empty()) - Needed.push_back({F, Out::DynStrTab->addString(F->getSoName())}); + Needed.push_back({F, In::DynStrTab->addString(F->getSoName())}); typename SharedFile::NeededVer &NV = F->VerdefMap[SS->Verdef]; // If we don't already know that we need an Elf_Vernaux for this Elf_Verdef, // prepare to create one by allocating a version identifier and creating a // dynstr entry for the version name. if (NV.Index == 0) { - NV.StrTab = Out::DynStrTab->addString( + NV.StrTab = In::DynStrTab->addString( SS->file()->getStringTable().data() + SS->Verdef->getAux()->vda_name); NV.Index = NextIndex++; } @@ -1438,7 +1413,7 @@ } template void VersionNeedSection::finalize() { - this->Link = Out::DynStrTab->SectionIndex; + this->Link = In::DynStrTab->OutSec->SectionIndex; this->Info = Needed.size(); unsigned Size = Needed.size() * sizeof(Elf_Verneed); for (std::pair *, size_t> &P : Needed) @@ -1590,11 +1565,6 @@ template class MergeOutputSection; template class MergeOutputSection; -template class StringTableSection; -template class StringTableSection; -template class StringTableSection; -template class StringTableSection; - template class SymbolTableSection; template class SymbolTableSection; template class SymbolTableSection; Index: lld/trunk/ELF/SyntheticSections.h =================================================================== --- lld/trunk/ELF/SyntheticSections.h +++ lld/trunk/ELF/SyntheticSections.h @@ -218,6 +218,26 @@ std::vector Entries; }; +template +class StringTableSection final : public SyntheticSection { +public: + typedef typename ELFT::uint uintX_t; + StringTableSection(StringRef Name, bool Dynamic); + unsigned addString(StringRef S, bool HashIt = true); + void writeTo(uint8_t *Buf) override; + size_t getSize() const override { return Size; } + bool isDynamic() const { return Dynamic; } + +private: + const bool Dynamic; + + // ELF string tables start with a NUL byte, so 1. + uintX_t Size = 1; + + llvm::DenseMap StringMap; + std::vector Strings; +}; + template InputSection *createCommonSection(); template InputSection *createInterpSection(); template MergeInputSection *createCommentSection(); @@ -226,22 +246,35 @@ template struct In { static BuildIdSection *BuildId; static InputSection *Common; + static StringTableSection *DynStrTab; static GotSection *Got; static GotPltSection *GotPlt; static InputSection *Interp; static MipsAbiFlagsSection *MipsAbiFlags; static MipsOptionsSection *MipsOptions; 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 StringTableSection *In::DynStrTab; template GotSection *In::Got; template GotPltSection *In::GotPlt; template InputSection *In::Interp; template MipsAbiFlagsSection *In::MipsAbiFlags; template MipsOptionsSection *In::MipsOptions; 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 @@ -642,6 +642,38 @@ } } +template +StringTableSection::StringTableSection(StringRef Name, bool Dynamic) + : SyntheticSection(Dynamic ? (uintX_t)SHF_ALLOC : 0, SHT_STRTAB, 1, + Name), + Dynamic(Dynamic) {} + +// Adds a string to the string table. If HashIt is true we hash and check for +// duplicates. It is optional because the name of global symbols are already +// uniqued and hashing them again has a big cost for a small value: uniquing +// them with some other string that happens to be the same. +template +unsigned StringTableSection::addString(StringRef S, bool HashIt) { + if (HashIt) { + auto R = StringMap.insert(std::make_pair(S, this->Size)); + if (!R.second) + return R.first->second; + } + unsigned Ret = this->Size; + this->Size = this->Size + S.size() + 1; + Strings.push_back(S); + return Ret; +} + +template void StringTableSection::writeTo(uint8_t *Buf) { + // ELF string tables start with NUL byte, so advance the pointer by one. + ++Buf; + for (StringRef S : Strings) { + memcpy(Buf, S.data(), S.size()); + Buf += S.size() + 1; + } +} + template InputSection *elf::createCommonSection(); template InputSection *elf::createCommonSection(); template InputSection *elf::createCommonSection(); @@ -711,3 +743,8 @@ template class elf::GotPltSection; template class elf::GotPltSection; template class elf::GotPltSection; + +template class elf::StringTableSection; +template class elf::StringTableSection; +template class elf::StringTableSection; +template class elf::StringTableSection; Index: lld/trunk/ELF/Writer.cpp =================================================================== --- lld/trunk/ELF/Writer.cpp +++ lld/trunk/ELF/Writer.cpp @@ -209,13 +209,13 @@ // Create singleton output sections. Out::Bss = make>(".bss", SHT_NOBITS, SHF_ALLOC | SHF_WRITE); - Out::DynStrTab = make>(".dynstr", true); + In::DynStrTab = make>(".dynstr", true); Out::Dynamic = make>(); Out::EhFrame = make>(); Out::Plt = make>(); Out::RelaDyn = make>( Config->Rela ? ".rela.dyn" : ".rel.dyn", Config->ZCombreloc); - Out::ShStrTab = make>(".shstrtab", false); + In::ShStrTab = make>(".shstrtab", false); Out::VerSym = make>(); Out::VerNeed = make>(); @@ -232,8 +232,7 @@ } if (!Symtab::X->getSharedFiles().empty() || Config->Pic) { - Out::DynSymTab = - make>(*Out::DynStrTab); + Out::DynSymTab = make>(*In::DynStrTab); } if (Config->EhFrameHdr) @@ -249,8 +248,8 @@ Out::RelaPlt = make>( Config->Rela ? ".rela.plt" : ".rel.plt", false /*Sort*/); if (Config->Strip != StripPolicy::All) { - Out::StrTab = make>(".strtab", false); - Out::SymTab = make>(*Out::StrTab); + In::StrTab = make>(".strtab", false); + Out::SymTab = make>(*In::StrTab); } if (Config->EMachine == EM_MIPS && !Config->Shared) { @@ -315,6 +314,13 @@ 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 @@ -734,6 +740,9 @@ template void Writer::addInputSec(InputSectionBase *IS) { + if (!IS) + return; + if (!IS->Live) { reportDiscarded(IS); return; @@ -918,7 +927,7 @@ unsigned I = 1; for (OutputSectionBase *Sec : OutputSections) { Sec->SectionIndex = I++; - Sec->ShName = Out::ShStrTab->addString(Sec->getName()); + Sec->ShName = In::ShStrTab->addString(Sec->getName()); } // Finalizers fix each section's size. @@ -968,8 +977,8 @@ if (Out::GdbIndex && Out::DebugInfo) Add(Out::GdbIndex); Add(Out::SymTab); - Add(Out::ShStrTab); - Add(Out::StrTab); + addInputSec(In::ShStrTab); + addInputSec(In::StrTab); if (Out::DynSymTab) { Add(Out::DynSymTab); @@ -983,7 +992,7 @@ Add(Out::GnuHashTab); Add(Out::HashTab); Add(Out::Dynamic); - Add(Out::DynStrTab); + addInputSec(In::DynStrTab); if (Out::RelaDyn->hasRelocs()) Add(Out::RelaDyn); Add(Out::MipsRldMap); @@ -999,13 +1008,10 @@ if (needsGot()) { In::Got->finalize(); addInputSec(In::Got); - In::Got->OutSec->assignOffsets(); } - if (!In::GotPlt->empty()) { + if (!In::GotPlt->empty()) addInputSec(In::GotPlt); - In::GotPlt->OutSec->assignOffsets(); - } if (!Out::Plt->empty()) Add(Out::Plt); @@ -1420,7 +1426,7 @@ EHdr->e_phnum = Phdrs.size(); EHdr->e_shentsize = sizeof(Elf_Shdr); EHdr->e_shnum = OutputSections.size() + 1; - EHdr->e_shstrndx = Out::ShStrTab->SectionIndex; + EHdr->e_shstrndx = In::ShStrTab->OutSec->SectionIndex; if (Config->EMachine == EM_ARM) // We don't currently use any features incompatible with EF_ARM_EABI_VER5,