[lld] r286799 - [ELF] Convert StringTableSection to input section
Eugene Leviant via llvm-commits
llvm-commits at lists.llvm.org
Mon Nov 14 01:16:01 PST 2016
Author: evgeny777
Date: Mon Nov 14 03:16:00 2016
New Revision: 286799
URL: http://llvm.org/viewvc/llvm-project?rev=286799&view=rev
Log:
[ELF] Convert StringTableSection to input section
Differential revision: https://reviews.llvm.org/D26549
Modified:
lld/trunk/ELF/OutputSections.cpp
lld/trunk/ELF/OutputSections.h
lld/trunk/ELF/SyntheticSections.cpp
lld/trunk/ELF/SyntheticSections.h
lld/trunk/ELF/Writer.cpp
Modified: lld/trunk/ELF/OutputSections.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/OutputSections.cpp?rev=286799&r1=286798&r2=286799&view=diff
==============================================================================
--- lld/trunk/ELF/OutputSections.cpp (original)
+++ lld/trunk/ELF/OutputSections.cpp Mon Nov 14 03:16:00 2016
@@ -415,15 +415,15 @@ template <class ELFT> void DynamicSectio
// 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 DynamicSectio
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 DynamicSectio
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
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 MergeOutputSe
}
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 SymbolTableSe
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
// 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 VersionNeedSe
}
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<ELF32B
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>;
Modified: lld/trunk/ELF/OutputSections.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/OutputSections.h?rev=286799&r1=286798&r2=286799&view=diff
==============================================================================
--- lld/trunk/ELF/OutputSections.h (original)
+++ lld/trunk/ELF/OutputSections.h Mon Nov 14 03:16:00 2016
@@ -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>
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;
Modified: lld/trunk/ELF/SyntheticSections.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/SyntheticSections.cpp?rev=286799&r1=286798&r2=286799&view=diff
==============================================================================
--- lld/trunk/ELF/SyntheticSections.cpp (original)
+++ lld/trunk/ELF/SyntheticSections.cpp Mon Nov 14 03:16:00 2016
@@ -642,6 +642,38 @@ template <class ELFT> void GotPltSection
}
}
+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<ELF32L
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>;
Modified: lld/trunk/ELF/SyntheticSections.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/SyntheticSections.h?rev=286799&r1=286798&r2=286799&view=diff
==============================================================================
--- lld/trunk/ELF/SyntheticSections.h (original)
+++ lld/trunk/ELF/SyntheticSections.h Mon Nov 14 03:16:00 2016
@@ -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<
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
Modified: lld/trunk/ELF/Writer.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Writer.cpp?rev=286799&r1=286798&r2=286799&view=diff
==============================================================================
--- lld/trunk/ELF/Writer.cpp (original)
+++ lld/trunk/ELF/Writer.cpp Mon Nov 14 03:16:00 2016
@@ -209,13 +209,13 @@ template <class ELFT> void Writer<ELFT>:
// 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>:
}
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>:
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>:
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>:
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>:
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>:
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>:
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>:
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,
More information about the llvm-commits
mailing list