diff options
author | Eugene Leviant <eleviant@accesssoftek.com> | 2016-11-14 09:16:00 +0000 |
---|---|---|
committer | Eugene Leviant <eleviant@accesssoftek.com> | 2016-11-14 09:16:00 +0000 |
commit | 22eb026886bee93fd75c5689f8913a73decf1cfc (patch) | |
tree | 1eb533f1c926077f87ea591d30f77cced865ccb9 | |
parent | e3d8026cc78dfcbe8b67124e2f49721e3b517cd4 (diff) | |
download | llvm-22eb026886bee93fd75c5689f8913a73decf1cfc.zip llvm-22eb026886bee93fd75c5689f8913a73decf1cfc.tar.gz llvm-22eb026886bee93fd75c5689f8913a73decf1cfc.tar.bz2 |
[ELF] Convert StringTableSection to input section
Differential revision: https://reviews.llvm.org/D26549
llvm-svn: 286799
-rw-r--r-- | lld/ELF/OutputSections.cpp | 76 | ||||
-rw-r--r-- | lld/ELF/OutputSections.h | 27 | ||||
-rw-r--r-- | lld/ELF/SyntheticSections.cpp | 37 | ||||
-rw-r--r-- | lld/ELF/SyntheticSections.h | 33 | ||||
-rw-r--r-- | lld/ELF/Writer.cpp | 36 |
5 files changed, 114 insertions, 95 deletions
diff --git a/lld/ELF/OutputSections.cpp b/lld/ELF/OutputSections.cpp index b1b71fe..047ebc0 100644 --- a/lld/ELF/OutputSections.cpp +++ b/lld/ELF/OutputSections.cpp @@ -415,15 +415,15 @@ template <class ELFT> void DynamicSection<ELFT>::addEntries() { // Add strings to .dynstr early so that .dynstr's size will be // fixed early. for (StringRef S : Config->AuxiliaryList) - Add({DT_AUXILIARY, Out<ELFT>::DynStrTab->addString(S)}); + Add({DT_AUXILIARY, In<ELFT>::DynStrTab->addString(S)}); if (!Config->RPath.empty()) Add({Config->EnableNewDtags ? DT_RUNPATH : DT_RPATH, - Out<ELFT>::DynStrTab->addString(Config->RPath)}); + In<ELFT>::DynStrTab->addString(Config->RPath)}); for (SharedFile<ELFT> *F : Symtab<ELFT>::X->getSharedFiles()) if (F->isNeeded()) - Add({DT_NEEDED, Out<ELFT>::DynStrTab->addString(F->getSoName())}); + Add({DT_NEEDED, In<ELFT>::DynStrTab->addString(F->getSoName())}); if (!Config->SoName.empty()) - Add({DT_SONAME, Out<ELFT>::DynStrTab->addString(Config->SoName)}); + Add({DT_SONAME, In<ELFT>::DynStrTab->addString(Config->SoName)}); // Set DT_FLAGS and DT_FLAGS_1. uint32_t DtFlags = 0; @@ -455,7 +455,7 @@ template <class ELFT> void DynamicSection<ELFT>::finalize() { if (this->Size) return; // Already finalized. - this->Link = Out<ELFT>::DynStrTab->SectionIndex; + this->Link = In<ELFT>::DynStrTab->OutSec->SectionIndex; if (Out<ELFT>::RelaDyn->hasRelocs()) { bool IsRela = Config->Rela; @@ -483,8 +483,8 @@ template <class ELFT> void DynamicSection<ELFT>::finalize() { Add({DT_SYMTAB, Out<ELFT>::DynSymTab}); Add({DT_SYMENT, sizeof(Elf_Sym)}); - Add({DT_STRTAB, Out<ELFT>::DynStrTab}); - Add({DT_STRSZ, Out<ELFT>::DynStrTab->Size}); + Add({DT_STRTAB, In<ELFT>::DynStrTab}); + Add({DT_STRSZ, In<ELFT>::DynStrTab->getSize()}); if (Out<ELFT>::GnuHashTab) Add({DT_GNU_HASH, Out<ELFT>::GnuHashTab}); if (Out<ELFT>::HashTab) @@ -650,6 +650,15 @@ template <class ELFT> void OutputSection<ELFT>::finalize() { this->Link = D->OutSec->SectionIndex; } } + + // Recalculate input section offsets if we own any synthetic section + for (auto *SS : In<ELFT>::SyntheticSections) + if (SS && this == SS->OutSec) { + this->Size = 0; + assignOffsets(); + break; + } + if (Type != SHT_RELA && Type != SHT_REL) return; this->Link = Out<ELFT>::SymTab->SectionIndex; @@ -1052,40 +1061,6 @@ template <class ELFT> void MergeOutputSection<ELFT>::finalizePieces() { } template <class ELFT> -StringTableSection<ELFT>::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 <class ELFT> -unsigned StringTableSection<ELFT>::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 <class ELFT> void StringTableSection<ELFT>::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 <class ELFT> typename ELFT::uint DynamicReloc<ELFT>::getOffset() const { if (OutputSec) return OutputSec->Addr + OffsetInSec; @@ -1148,7 +1123,7 @@ template <class ELFT> void SymbolTableSection<ELFT>::finalize() { 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 @@ static StringRef getFileDefName() { } template <class ELFT> void VersionDefinitionSection<ELFT>::finalize() { - FileDefNameOff = Out<ELFT>::DynStrTab->addString(getFileDefName()); + FileDefNameOff = In<ELFT>::DynStrTab->addString(getFileDefName()); for (VersionDefinition &V : Config->VersionDefinitions) - V.NameOff = Out<ELFT>::DynStrTab->addString(V.Name); + V.NameOff = In<ELFT>::DynStrTab->addString(V.Name); this->Size = (sizeof(Elf_Verdef) + sizeof(Elf_Verdaux)) * getVerDefNum(); - this->Link = Out<ELFT>::DynStrTab->SectionIndex; + this->Link = In<ELFT>::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 @@ void VersionNeedSection<ELFT>::addSymbol(SharedSymbol<ELFT> *SS) { // 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<ELFT>::DynStrTab->addString(F->getSoName())}); + Needed.push_back({F, In<ELFT>::DynStrTab->addString(F->getSoName())}); typename SharedFile<ELFT>::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<ELFT>::DynStrTab->addString( + NV.StrTab = In<ELFT>::DynStrTab->addString( SS->file()->getStringTable().data() + SS->Verdef->getAux()->vda_name); NV.Index = NextIndex++; } @@ -1438,7 +1413,7 @@ template <class ELFT> void VersionNeedSection<ELFT>::writeTo(uint8_t *Buf) { } template <class ELFT> void VersionNeedSection<ELFT>::finalize() { - this->Link = Out<ELFT>::DynStrTab->SectionIndex; + this->Link = In<ELFT>::DynStrTab->OutSec->SectionIndex; this->Info = Needed.size(); unsigned Size = Needed.size() * sizeof(Elf_Verneed); for (std::pair<SharedFile<ELFT> *, size_t> &P : Needed) @@ -1590,11 +1565,6 @@ template class MergeOutputSection<ELF32BE>; template class MergeOutputSection<ELF64LE>; template class MergeOutputSection<ELF64BE>; -template class StringTableSection<ELF32LE>; -template class StringTableSection<ELF32BE>; -template class StringTableSection<ELF64LE>; -template class StringTableSection<ELF64BE>; - template class SymbolTableSection<ELF32LE>; template class SymbolTableSection<ELF32BE>; template class SymbolTableSection<ELF64LE>; diff --git a/lld/ELF/OutputSections.h b/lld/ELF/OutputSections.h index 1ef379e..bc82039 100644 --- a/lld/ELF/OutputSections.h +++ b/lld/ELF/OutputSections.h @@ -54,7 +54,6 @@ public: Plt, Regular, Reloc, - StrTable, SymTable, VersDef, VersNeed, @@ -424,26 +423,6 @@ private: llvm::DenseMap<std::pair<ArrayRef<uint8_t>, SymbolBody *>, CieRecord> CieMap; }; -template <class ELFT> -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<StringRef, unsigned> StringMap; - std::vector<StringRef> Strings; -}; - template <class ELFT> class HashTableSection final : public OutputSectionBase { typedef typename ELFT::Word Elf_Word; @@ -600,9 +579,6 @@ template <class ELFT> struct Out { static PltSection<ELFT> *Plt; static RelocationSection<ELFT> *RelaDyn; static RelocationSection<ELFT> *RelaPlt; - static StringTableSection<ELFT> *DynStrTab; - static StringTableSection<ELFT> *ShStrTab; - static StringTableSection<ELFT> *StrTab; static SymbolTableSection<ELFT> *DynSymTab; static SymbolTableSection<ELFT> *SymTab; static VersionDefinitionSection<ELFT> *VerDef; @@ -664,9 +640,6 @@ template <class ELFT> uint8_t *Out<ELFT>::OpdBuf; template <class ELFT> PltSection<ELFT> *Out<ELFT>::Plt; template <class ELFT> RelocationSection<ELFT> *Out<ELFT>::RelaDyn; template <class ELFT> RelocationSection<ELFT> *Out<ELFT>::RelaPlt; -template <class ELFT> StringTableSection<ELFT> *Out<ELFT>::DynStrTab; -template <class ELFT> StringTableSection<ELFT> *Out<ELFT>::ShStrTab; -template <class ELFT> StringTableSection<ELFT> *Out<ELFT>::StrTab; template <class ELFT> SymbolTableSection<ELFT> *Out<ELFT>::DynSymTab; template <class ELFT> SymbolTableSection<ELFT> *Out<ELFT>::SymTab; template <class ELFT> VersionDefinitionSection<ELFT> *Out<ELFT>::VerDef; diff --git a/lld/ELF/SyntheticSections.cpp b/lld/ELF/SyntheticSections.cpp index b4dc1e6..38a8941 100644 --- a/lld/ELF/SyntheticSections.cpp +++ b/lld/ELF/SyntheticSections.cpp @@ -642,6 +642,38 @@ template <class ELFT> void GotPltSection<ELFT>::writeTo(uint8_t *Buf) { } } +template <class ELFT> +StringTableSection<ELFT>::StringTableSection(StringRef Name, bool Dynamic) + : SyntheticSection<ELFT>(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 <class ELFT> +unsigned StringTableSection<ELFT>::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 <class ELFT> void StringTableSection<ELFT>::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<ELF32LE> *elf::createCommonSection(); template InputSection<ELF32BE> *elf::createCommonSection(); template InputSection<ELF64LE> *elf::createCommonSection(); @@ -711,3 +743,8 @@ template class elf::GotPltSection<ELF32LE>; template class elf::GotPltSection<ELF32BE>; template class elf::GotPltSection<ELF64LE>; template class elf::GotPltSection<ELF64BE>; + +template class elf::StringTableSection<ELF32LE>; +template class elf::StringTableSection<ELF32BE>; +template class elf::StringTableSection<ELF64LE>; +template class elf::StringTableSection<ELF64BE>; diff --git a/lld/ELF/SyntheticSections.h b/lld/ELF/SyntheticSections.h index f41a18f..2f16595 100644 --- a/lld/ELF/SyntheticSections.h +++ b/lld/ELF/SyntheticSections.h @@ -218,6 +218,26 @@ private: std::vector<const SymbolBody *> Entries; }; +template <class ELFT> +class StringTableSection final : public SyntheticSection<ELFT> { +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<StringRef, unsigned> StringMap; + std::vector<StringRef> Strings; +}; + template <class ELFT> InputSection<ELFT> *createCommonSection(); template <class ELFT> InputSection<ELFT> *createInterpSection(); template <class ELFT> MergeInputSection<ELFT> *createCommentSection(); @@ -226,22 +246,35 @@ template <class ELFT> MergeInputSection<ELFT> *createCommentSection(); template <class ELFT> struct In { static BuildIdSection<ELFT> *BuildId; static InputSection<ELFT> *Common; + static StringTableSection<ELFT> *DynStrTab; static GotSection<ELFT> *Got; static GotPltSection<ELFT> *GotPlt; static InputSection<ELFT> *Interp; static MipsAbiFlagsSection<ELFT> *MipsAbiFlags; static MipsOptionsSection<ELFT> *MipsOptions; static MipsReginfoSection<ELFT> *MipsReginfo; + static StringTableSection<ELFT> *ShStrTab; + static StringTableSection<ELFT> *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<SyntheticSection<ELFT> *> SyntheticSections; }; template <class ELFT> BuildIdSection<ELFT> *In<ELFT>::BuildId; template <class ELFT> InputSection<ELFT> *In<ELFT>::Common; +template <class ELFT> StringTableSection<ELFT> *In<ELFT>::DynStrTab; template <class ELFT> GotSection<ELFT> *In<ELFT>::Got; template <class ELFT> GotPltSection<ELFT> *In<ELFT>::GotPlt; template <class ELFT> InputSection<ELFT> *In<ELFT>::Interp; template <class ELFT> MipsAbiFlagsSection<ELFT> *In<ELFT>::MipsAbiFlags; template <class ELFT> MipsOptionsSection<ELFT> *In<ELFT>::MipsOptions; template <class ELFT> MipsReginfoSection<ELFT> *In<ELFT>::MipsReginfo; +template <class ELFT> StringTableSection<ELFT> *In<ELFT>::ShStrTab; +template <class ELFT> StringTableSection<ELFT> *In<ELFT>::StrTab; +template <class ELFT> +std::vector<SyntheticSection<ELFT> *> In<ELFT>::SyntheticSections; } // namespace elf } // namespace lld diff --git a/lld/ELF/Writer.cpp b/lld/ELF/Writer.cpp index 7622484a..5e70b91 100644 --- a/lld/ELF/Writer.cpp +++ b/lld/ELF/Writer.cpp @@ -209,13 +209,13 @@ template <class ELFT> void Writer<ELFT>::createSyntheticSections() { // Create singleton output sections. Out<ELFT>::Bss = make<OutputSection<ELFT>>(".bss", SHT_NOBITS, SHF_ALLOC | SHF_WRITE); - Out<ELFT>::DynStrTab = make<StringTableSection<ELFT>>(".dynstr", true); + In<ELFT>::DynStrTab = make<StringTableSection<ELFT>>(".dynstr", true); Out<ELFT>::Dynamic = make<DynamicSection<ELFT>>(); Out<ELFT>::EhFrame = make<EhOutputSection<ELFT>>(); Out<ELFT>::Plt = make<PltSection<ELFT>>(); Out<ELFT>::RelaDyn = make<RelocationSection<ELFT>>( Config->Rela ? ".rela.dyn" : ".rel.dyn", Config->ZCombreloc); - Out<ELFT>::ShStrTab = make<StringTableSection<ELFT>>(".shstrtab", false); + In<ELFT>::ShStrTab = make<StringTableSection<ELFT>>(".shstrtab", false); Out<ELFT>::VerSym = make<VersionTableSection<ELFT>>(); Out<ELFT>::VerNeed = make<VersionNeedSection<ELFT>>(); @@ -232,8 +232,7 @@ template <class ELFT> void Writer<ELFT>::createSyntheticSections() { } if (!Symtab<ELFT>::X->getSharedFiles().empty() || Config->Pic) { - Out<ELFT>::DynSymTab = - make<SymbolTableSection<ELFT>>(*Out<ELFT>::DynStrTab); + Out<ELFT>::DynSymTab = make<SymbolTableSection<ELFT>>(*In<ELFT>::DynStrTab); } if (Config->EhFrameHdr) @@ -249,8 +248,8 @@ template <class ELFT> void Writer<ELFT>::createSyntheticSections() { Out<ELFT>::RelaPlt = make<RelocationSection<ELFT>>( Config->Rela ? ".rela.plt" : ".rel.plt", false /*Sort*/); if (Config->Strip != StripPolicy::All) { - Out<ELFT>::StrTab = make<StringTableSection<ELFT>>(".strtab", false); - Out<ELFT>::SymTab = make<SymbolTableSection<ELFT>>(*Out<ELFT>::StrTab); + In<ELFT>::StrTab = make<StringTableSection<ELFT>>(".strtab", false); + Out<ELFT>::SymTab = make<SymbolTableSection<ELFT>>(*In<ELFT>::StrTab); } if (Config->EMachine == EM_MIPS && !Config->Shared) { @@ -315,6 +314,13 @@ template <class ELFT> void Writer<ELFT>::createSyntheticSections() { In<ELFT>::Got = make<GotSection<ELFT>>(); In<ELFT>::GotPlt = make<GotPltSection<ELFT>>(); + + // These sections are filled after createSections() is called. + // We use this list to fixup size of output sections, when they + // are finalized. + In<ELFT>::SyntheticSections = {In<ELFT>::ShStrTab, In<ELFT>::StrTab, + In<ELFT>::DynStrTab, In<ELFT>::Got, + In<ELFT>::GotPlt}; } template <class ELFT> @@ -734,6 +740,9 @@ void Writer<ELFT>::forEachRelSec( template <class ELFT> void Writer<ELFT>::addInputSec(InputSectionBase<ELFT> *IS) { + if (!IS) + return; + if (!IS->Live) { reportDiscarded(IS); return; @@ -918,7 +927,7 @@ template <class ELFT> void Writer<ELFT>::finalizeSections() { unsigned I = 1; for (OutputSectionBase *Sec : OutputSections) { Sec->SectionIndex = I++; - Sec->ShName = Out<ELFT>::ShStrTab->addString(Sec->getName()); + Sec->ShName = In<ELFT>::ShStrTab->addString(Sec->getName()); } // Finalizers fix each section's size. @@ -968,8 +977,8 @@ template <class ELFT> void Writer<ELFT>::addPredefinedSections() { if (Out<ELFT>::GdbIndex && Out<ELFT>::DebugInfo) Add(Out<ELFT>::GdbIndex); Add(Out<ELFT>::SymTab); - Add(Out<ELFT>::ShStrTab); - Add(Out<ELFT>::StrTab); + addInputSec(In<ELFT>::ShStrTab); + addInputSec(In<ELFT>::StrTab); if (Out<ELFT>::DynSymTab) { Add(Out<ELFT>::DynSymTab); @@ -983,7 +992,7 @@ template <class ELFT> void Writer<ELFT>::addPredefinedSections() { Add(Out<ELFT>::GnuHashTab); Add(Out<ELFT>::HashTab); Add(Out<ELFT>::Dynamic); - Add(Out<ELFT>::DynStrTab); + addInputSec(In<ELFT>::DynStrTab); if (Out<ELFT>::RelaDyn->hasRelocs()) Add(Out<ELFT>::RelaDyn); Add(Out<ELFT>::MipsRldMap); @@ -999,13 +1008,10 @@ template <class ELFT> void Writer<ELFT>::addPredefinedSections() { if (needsGot()) { In<ELFT>::Got->finalize(); addInputSec(In<ELFT>::Got); - In<ELFT>::Got->OutSec->assignOffsets(); } - if (!In<ELFT>::GotPlt->empty()) { + if (!In<ELFT>::GotPlt->empty()) addInputSec(In<ELFT>::GotPlt); - In<ELFT>::GotPlt->OutSec->assignOffsets(); - } if (!Out<ELFT>::Plt->empty()) Add(Out<ELFT>::Plt); @@ -1420,7 +1426,7 @@ template <class ELFT> void Writer<ELFT>::writeHeader() { EHdr->e_phnum = Phdrs.size(); EHdr->e_shentsize = sizeof(Elf_Shdr); EHdr->e_shnum = OutputSections.size() + 1; - EHdr->e_shstrndx = Out<ELFT>::ShStrTab->SectionIndex; + EHdr->e_shstrndx = In<ELFT>::ShStrTab->OutSec->SectionIndex; if (Config->EMachine == EM_ARM) // We don't currently use any features incompatible with EF_ARM_EABI_VER5, |