De-template VersionDefinitionSection. NFC.

When we write a struct to a mmap'ed buffer, we usually use
write16/32/64, but we didn't for VersionDefinitionSection, so
we needed to template that class.

llvm-svn: 343024
This commit is contained in:
Rui Ueyama 2018-09-25 20:37:51 +00:00
parent 75606b285c
commit 12ef7a9575
4 changed files with 37 additions and 50 deletions

View File

@ -1402,7 +1402,6 @@ static const char *LibcallRoutineNames[] = {
// all linker scripts have already been parsed. // all linker scripts have already been parsed.
template <class ELFT> void LinkerDriver::link(opt::InputArgList &Args) { template <class ELFT> void LinkerDriver::link(opt::InputArgList &Args) {
Target = getTarget(); Target = getTarget();
InX<ELFT>::VerDef = nullptr;
InX<ELFT>::VerSym = nullptr; InX<ELFT>::VerSym = nullptr;
InX<ELFT>::VerNeed = nullptr; InX<ELFT>::VerNeed = nullptr;

View File

@ -1383,10 +1383,10 @@ template <class ELFT> void DynamicSection<ELFT>::finalizeContents() {
addSym(DT_FINI, B); addSym(DT_FINI, B);
bool HasVerNeed = InX<ELFT>::VerNeed->getNeedNum() != 0; bool HasVerNeed = InX<ELFT>::VerNeed->getNeedNum() != 0;
if (HasVerNeed || InX<ELFT>::VerDef) if (HasVerNeed || In.VerDef)
addInSec(DT_VERSYM, InX<ELFT>::VerSym); addInSec(DT_VERSYM, InX<ELFT>::VerSym);
if (InX<ELFT>::VerDef) { if (In.VerDef) {
addInSec(DT_VERDEF, InX<ELFT>::VerDef); addInSec(DT_VERDEF, In.VerDef);
addInt(DT_VERDEFNUM, getVerDefNum()); addInt(DT_VERDEFNUM, getVerDefNum());
} }
if (HasVerNeed) { if (HasVerNeed) {
@ -2627,8 +2627,7 @@ size_t EhFrameHeader::getSize() const {
bool EhFrameHeader::empty() const { return In.EhFrame->empty(); } bool EhFrameHeader::empty() const { return In.EhFrame->empty(); }
template <class ELFT> VersionDefinitionSection::VersionDefinitionSection()
VersionDefinitionSection<ELFT>::VersionDefinitionSection()
: SyntheticSection(SHF_ALLOC, SHT_GNU_verdef, sizeof(uint32_t), : SyntheticSection(SHF_ALLOC, SHT_GNU_verdef, sizeof(uint32_t),
".gnu.version_d") {} ".gnu.version_d") {}
@ -2638,7 +2637,7 @@ static StringRef getFileDefName() {
return Config->OutputFile; return Config->OutputFile;
} }
template <class ELFT> void VersionDefinitionSection<ELFT>::finalizeContents() { void VersionDefinitionSection::finalizeContents() {
FileDefNameOff = In.DynStrTab->addString(getFileDefName()); FileDefNameOff = In.DynStrTab->addString(getFileDefName());
for (VersionDefinition &V : Config->VersionDefinitions) for (VersionDefinition &V : Config->VersionDefinitions)
V.NameOff = In.DynStrTab->addString(V.Name); V.NameOff = In.DynStrTab->addString(V.Name);
@ -2651,46 +2650,46 @@ template <class ELFT> void VersionDefinitionSection<ELFT>::finalizeContents() {
getParent()->Info = getVerDefNum(); getParent()->Info = getVerDefNum();
} }
template <class ELFT> void VersionDefinitionSection::writeOne(uint8_t *Buf, uint32_t Index,
void VersionDefinitionSection<ELFT>::writeOne(uint8_t *Buf, uint32_t Index, StringRef Name, size_t NameOff) {
StringRef Name, size_t NameOff) { uint16_t Flags = Index == 1 ? VER_FLG_BASE : 0;
auto *Verdef = reinterpret_cast<Elf_Verdef *>(Buf);
Verdef->vd_version = 1;
Verdef->vd_cnt = 1;
Verdef->vd_aux = sizeof(Elf_Verdef);
Verdef->vd_next = sizeof(Elf_Verdef) + sizeof(Elf_Verdaux);
Verdef->vd_flags = (Index == 1 ? VER_FLG_BASE : 0);
Verdef->vd_ndx = Index;
Verdef->vd_hash = hashSysV(Name);
auto *Verdaux = reinterpret_cast<Elf_Verdaux *>(Buf + sizeof(Elf_Verdef)); // Write a verdef.
Verdaux->vda_name = NameOff; write16(Buf, 1); // vd_version
Verdaux->vda_next = 0; write16(Buf + 2, Flags); // vd_flags
write16(Buf + 4, Index); // vd_ndx
write16(Buf + 6, 1); // vd_cnt
write32(Buf + 8, hashSysV(Name)); // vd_hash
write32(Buf + 12, 20); // vd_aux
write32(Buf + 16, 28); // vd_next
// Write a veraux.
write32(Buf + 20, NameOff); // vda_name
write32(Buf + 24, 0); // vda_next
} }
template <class ELFT> void VersionDefinitionSection::writeTo(uint8_t *Buf) {
void VersionDefinitionSection<ELFT>::writeTo(uint8_t *Buf) {
writeOne(Buf, 1, getFileDefName(), FileDefNameOff); writeOne(Buf, 1, getFileDefName(), FileDefNameOff);
for (VersionDefinition &V : Config->VersionDefinitions) { for (VersionDefinition &V : Config->VersionDefinitions) {
Buf += sizeof(Elf_Verdef) + sizeof(Elf_Verdaux); Buf += EntrySize;
writeOne(Buf, V.Id, V.Name, V.NameOff); writeOne(Buf, V.Id, V.Name, V.NameOff);
} }
// Need to terminate the last version definition. // Need to terminate the last version definition.
Elf_Verdef *Verdef = reinterpret_cast<Elf_Verdef *>(Buf); write32(Buf + 16, 0); // vd_next
Verdef->vd_next = 0;
} }
template <class ELFT> size_t VersionDefinitionSection<ELFT>::getSize() const { size_t VersionDefinitionSection::getSize() const {
return (sizeof(Elf_Verdef) + sizeof(Elf_Verdaux)) * getVerDefNum(); return EntrySize * getVerDefNum();
} }
// .gnu.version is a table where each entry is 2 byte long.
template <class ELFT> template <class ELFT>
VersionTableSection<ELFT>::VersionTableSection() VersionTableSection<ELFT>::VersionTableSection()
: SyntheticSection(SHF_ALLOC, SHT_GNU_versym, sizeof(uint16_t), : SyntheticSection(SHF_ALLOC, SHT_GNU_versym, sizeof(uint16_t),
".gnu.version") { ".gnu.version") {
this->Entsize = sizeof(Elf_Versym); this->Entsize = 2;
} }
template <class ELFT> void VersionTableSection<ELFT>::finalizeContents() { template <class ELFT> void VersionTableSection<ELFT>::finalizeContents() {
@ -2700,19 +2699,19 @@ template <class ELFT> void VersionTableSection<ELFT>::finalizeContents() {
} }
template <class ELFT> size_t VersionTableSection<ELFT>::getSize() const { template <class ELFT> size_t VersionTableSection<ELFT>::getSize() const {
return sizeof(Elf_Versym) * (In.DynSymTab->getSymbols().size() + 1); return (In.DynSymTab->getSymbols().size() + 1) * 2;
} }
template <class ELFT> void VersionTableSection<ELFT>::writeTo(uint8_t *Buf) { template <class ELFT> void VersionTableSection<ELFT>::writeTo(uint8_t *Buf) {
auto *OutVersym = reinterpret_cast<Elf_Versym *>(Buf) + 1; Buf += 2;
for (const SymbolTableEntry &S : In.DynSymTab->getSymbols()) { for (const SymbolTableEntry &S : In.DynSymTab->getSymbols()) {
OutVersym->vs_index = S.Sym->VersionId; write16(Buf, S.Sym->VersionId);
++OutVersym; Buf += 2;
} }
} }
template <class ELFT> bool VersionTableSection<ELFT>::empty() const { template <class ELFT> bool VersionTableSection<ELFT>::empty() const {
return !InX<ELFT>::VerDef && InX<ELFT>::VerNeed->empty(); return !In.VerDef && InX<ELFT>::VerNeed->empty();
} }
template <class ELFT> template <class ELFT>
@ -3123,8 +3122,3 @@ template class elf::VersionNeedSection<ELF32LE>;
template class elf::VersionNeedSection<ELF32BE>; template class elf::VersionNeedSection<ELF32BE>;
template class elf::VersionNeedSection<ELF64LE>; template class elf::VersionNeedSection<ELF64LE>;
template class elf::VersionNeedSection<ELF64BE>; template class elf::VersionNeedSection<ELF64BE>;
template class elf::VersionDefinitionSection<ELF32LE>;
template class elf::VersionDefinitionSection<ELF32BE>;
template class elf::VersionDefinitionSection<ELF64LE>;
template class elf::VersionDefinitionSection<ELF64BE>;

View File

@ -757,11 +757,7 @@ public:
// shall be contained in the DT_VERDEFNUM entry of the .dynamic section. // shall be contained in the DT_VERDEFNUM entry of the .dynamic section.
// The section shall contain an array of Elf_Verdef structures, optionally // The section shall contain an array of Elf_Verdef structures, optionally
// followed by an array of Elf_Verdaux structures. // followed by an array of Elf_Verdaux structures.
template <class ELFT>
class VersionDefinitionSection final : public SyntheticSection { class VersionDefinitionSection final : public SyntheticSection {
typedef typename ELFT::Verdef Elf_Verdef;
typedef typename ELFT::Verdaux Elf_Verdaux;
public: public:
VersionDefinitionSection(); VersionDefinitionSection();
void finalizeContents() override; void finalizeContents() override;
@ -769,6 +765,7 @@ public:
void writeTo(uint8_t *Buf) override; void writeTo(uint8_t *Buf) override;
private: private:
enum { EntrySize = 28 };
void writeOne(uint8_t *Buf, uint32_t Index, StringRef Name, size_t NameOff); void writeOne(uint8_t *Buf, uint32_t Index, StringRef Name, size_t NameOff);
unsigned FileDefNameOff; unsigned FileDefNameOff;
@ -782,8 +779,6 @@ private:
// the own object or in any of the dependencies. // the own object or in any of the dependencies.
template <class ELFT> template <class ELFT>
class VersionTableSection final : public SyntheticSection { class VersionTableSection final : public SyntheticSection {
typedef typename ELFT::Versym Elf_Versym;
public: public:
VersionTableSection(); VersionTableSection();
void finalizeContents() override; void finalizeContents() override;
@ -1012,17 +1007,16 @@ struct InStruct {
StringTableSection *StrTab; StringTableSection *StrTab;
SymbolTableBaseSection *SymTab; SymbolTableBaseSection *SymTab;
SymtabShndxSection *SymTabShndx; SymtabShndxSection *SymTabShndx;
VersionDefinitionSection *VerDef;
}; };
extern InStruct In; extern InStruct In;
template <class ELFT> struct InX { template <class ELFT> struct InX {
static VersionDefinitionSection<ELFT> *VerDef;
static VersionTableSection<ELFT> *VerSym; static VersionTableSection<ELFT> *VerSym;
static VersionNeedSection<ELFT> *VerNeed; static VersionNeedSection<ELFT> *VerNeed;
}; };
template <class ELFT> VersionDefinitionSection<ELFT> *InX<ELFT>::VerDef;
template <class ELFT> VersionTableSection<ELFT> *InX<ELFT>::VerSym; template <class ELFT> VersionTableSection<ELFT> *InX<ELFT>::VerSym;
template <class ELFT> VersionNeedSection<ELFT> *InX<ELFT>::VerNeed; template <class ELFT> VersionNeedSection<ELFT> *InX<ELFT>::VerNeed;
} // namespace elf } // namespace elf

View File

@ -323,8 +323,8 @@ template <class ELFT> static void createSyntheticSections() {
Add(InX<ELFT>::VerSym); Add(InX<ELFT>::VerSym);
if (!Config->VersionDefinitions.empty()) { if (!Config->VersionDefinitions.empty()) {
InX<ELFT>::VerDef = make<VersionDefinitionSection<ELFT>>(); In.VerDef = make<VersionDefinitionSection>();
Add(InX<ELFT>::VerDef); Add(In.VerDef);
} }
InX<ELFT>::VerNeed = make<VersionNeedSection<ELFT>>(); InX<ELFT>::VerNeed = make<VersionNeedSection<ELFT>>();
@ -1675,7 +1675,7 @@ template <class ELFT> void Writer<ELFT>::finalizeSections() {
In.SymTabShndx, In.SymTabShndx,
In.ShStrTab, In.ShStrTab,
In.StrTab, In.StrTab,
InX<ELFT>::VerDef, In.VerDef,
In.DynStrTab, In.DynStrTab,
In.Got, In.Got,
In.MipsGot, In.MipsGot,