Skip to content

Commit

Permalink
[ELF] Convert StringTableSection to input section
Browse files Browse the repository at this point in the history
Differential revision: https://reviews.llvm.org/D26549

llvm-svn: 286799
  • Loading branch information
eleviant committed Nov 14, 2016
1 parent e3d8026 commit 22eb026
Show file tree
Hide file tree
Showing 5 changed files with 114 additions and 95 deletions.
76 changes: 23 additions & 53 deletions lld/ELF/OutputSections.cpp
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -1051,40 +1060,6 @@ template <class ELFT> void MergeOutputSection<ELFT>::finalizePieces() {
Sec->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)
Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -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:
Expand Down Expand Up @@ -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++;
}
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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>;
Expand Down
27 changes: 0 additions & 27 deletions lld/ELF/OutputSections.h
Expand Up @@ -54,7 +54,6 @@ class OutputSectionBase {
Plt,
Regular,
Reloc,
StrTable,
SymTable,
VersDef,
VersNeed,
Expand Down Expand Up @@ -424,26 +423,6 @@ template <class ELFT> class EhOutputSection final : public OutputSectionBase {
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;

Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down
37 changes: 37 additions & 0 deletions lld/ELF/SyntheticSections.cpp
Expand Up @@ -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();
Expand Down Expand Up @@ -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>;
33 changes: 33 additions & 0 deletions lld/ELF/SyntheticSections.h
Expand Up @@ -218,6 +218,26 @@ class GotPltSection final : public SyntheticSection<ELFT> {
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();
Expand All @@ -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
Expand Down

0 comments on commit 22eb026

Please sign in to comment.