diff options
-rw-r--r-- | lld/ELF/Driver.cpp | 1 | ||||
-rw-r--r-- | lld/ELF/SyntheticSections.cpp | 72 | ||||
-rw-r--r-- | lld/ELF/SyntheticSections.h | 10 | ||||
-rw-r--r-- | lld/ELF/Writer.cpp | 6 |
4 files changed, 38 insertions, 51 deletions
diff --git a/lld/ELF/Driver.cpp b/lld/ELF/Driver.cpp index 11810182f70..019c2ce3049 100644 --- a/lld/ELF/Driver.cpp +++ b/lld/ELF/Driver.cpp @@ -1402,7 +1402,6 @@ static const char *LibcallRoutineNames[] = { // all linker scripts have already been parsed. template <class ELFT> void LinkerDriver::link(opt::InputArgList &Args) { Target = getTarget(); - InX<ELFT>::VerDef = nullptr; InX<ELFT>::VerSym = nullptr; InX<ELFT>::VerNeed = nullptr; diff --git a/lld/ELF/SyntheticSections.cpp b/lld/ELF/SyntheticSections.cpp index 1f86571c00e..2fbc4f96f82 100644 --- a/lld/ELF/SyntheticSections.cpp +++ b/lld/ELF/SyntheticSections.cpp @@ -1383,10 +1383,10 @@ template <class ELFT> void DynamicSection<ELFT>::finalizeContents() { addSym(DT_FINI, B); bool HasVerNeed = InX<ELFT>::VerNeed->getNeedNum() != 0; - if (HasVerNeed || InX<ELFT>::VerDef) + if (HasVerNeed || In.VerDef) addInSec(DT_VERSYM, InX<ELFT>::VerSym); - if (InX<ELFT>::VerDef) { - addInSec(DT_VERDEF, InX<ELFT>::VerDef); + if (In.VerDef) { + addInSec(DT_VERDEF, In.VerDef); addInt(DT_VERDEFNUM, getVerDefNum()); } if (HasVerNeed) { @@ -2627,8 +2627,7 @@ size_t EhFrameHeader::getSize() const { bool EhFrameHeader::empty() const { return In.EhFrame->empty(); } -template <class ELFT> -VersionDefinitionSection<ELFT>::VersionDefinitionSection() +VersionDefinitionSection::VersionDefinitionSection() : SyntheticSection(SHF_ALLOC, SHT_GNU_verdef, sizeof(uint32_t), ".gnu.version_d") {} @@ -2638,7 +2637,7 @@ static StringRef getFileDefName() { return Config->OutputFile; } -template <class ELFT> void VersionDefinitionSection<ELFT>::finalizeContents() { +void VersionDefinitionSection::finalizeContents() { FileDefNameOff = In.DynStrTab->addString(getFileDefName()); for (VersionDefinition &V : Config->VersionDefinitions) V.NameOff = In.DynStrTab->addString(V.Name); @@ -2651,46 +2650,46 @@ template <class ELFT> void VersionDefinitionSection<ELFT>::finalizeContents() { getParent()->Info = getVerDefNum(); } -template <class ELFT> -void VersionDefinitionSection<ELFT>::writeOne(uint8_t *Buf, uint32_t Index, - StringRef Name, size_t NameOff) { - 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)); - Verdaux->vda_name = NameOff; - Verdaux->vda_next = 0; +void VersionDefinitionSection::writeOne(uint8_t *Buf, uint32_t Index, + StringRef Name, size_t NameOff) { + uint16_t Flags = Index == 1 ? VER_FLG_BASE : 0; + + // Write a verdef. + write16(Buf, 1); // vd_version + 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<ELFT>::writeTo(uint8_t *Buf) { +void VersionDefinitionSection::writeTo(uint8_t *Buf) { writeOne(Buf, 1, getFileDefName(), FileDefNameOff); for (VersionDefinition &V : Config->VersionDefinitions) { - Buf += sizeof(Elf_Verdef) + sizeof(Elf_Verdaux); + Buf += EntrySize; writeOne(Buf, V.Id, V.Name, V.NameOff); } // Need to terminate the last version definition. - Elf_Verdef *Verdef = reinterpret_cast<Elf_Verdef *>(Buf); - Verdef->vd_next = 0; + write32(Buf + 16, 0); // vd_next } -template <class ELFT> size_t VersionDefinitionSection<ELFT>::getSize() const { - return (sizeof(Elf_Verdef) + sizeof(Elf_Verdaux)) * getVerDefNum(); +size_t VersionDefinitionSection::getSize() const { + return EntrySize * getVerDefNum(); } +// .gnu.version is a table where each entry is 2 byte long. template <class ELFT> VersionTableSection<ELFT>::VersionTableSection() : SyntheticSection(SHF_ALLOC, SHT_GNU_versym, sizeof(uint16_t), ".gnu.version") { - this->Entsize = sizeof(Elf_Versym); + this->Entsize = 2; } 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 { - 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) { - auto *OutVersym = reinterpret_cast<Elf_Versym *>(Buf) + 1; + Buf += 2; for (const SymbolTableEntry &S : In.DynSymTab->getSymbols()) { - OutVersym->vs_index = S.Sym->VersionId; - ++OutVersym; + write16(Buf, S.Sym->VersionId); + Buf += 2; } } 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> @@ -3123,8 +3122,3 @@ template class elf::VersionNeedSection<ELF32LE>; template class elf::VersionNeedSection<ELF32BE>; template class elf::VersionNeedSection<ELF64LE>; 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>; diff --git a/lld/ELF/SyntheticSections.h b/lld/ELF/SyntheticSections.h index cd1eb643eab..d97a57d6c1a 100644 --- a/lld/ELF/SyntheticSections.h +++ b/lld/ELF/SyntheticSections.h @@ -757,11 +757,7 @@ public: // shall be contained in the DT_VERDEFNUM entry of the .dynamic section. // The section shall contain an array of Elf_Verdef structures, optionally // followed by an array of Elf_Verdaux structures. -template <class ELFT> class VersionDefinitionSection final : public SyntheticSection { - typedef typename ELFT::Verdef Elf_Verdef; - typedef typename ELFT::Verdaux Elf_Verdaux; - public: VersionDefinitionSection(); void finalizeContents() override; @@ -769,6 +765,7 @@ public: void writeTo(uint8_t *Buf) override; private: + enum { EntrySize = 28 }; void writeOne(uint8_t *Buf, uint32_t Index, StringRef Name, size_t NameOff); unsigned FileDefNameOff; @@ -782,8 +779,6 @@ private: // the own object or in any of the dependencies. template <class ELFT> class VersionTableSection final : public SyntheticSection { - typedef typename ELFT::Versym Elf_Versym; - public: VersionTableSection(); void finalizeContents() override; @@ -1012,17 +1007,16 @@ struct InStruct { StringTableSection *StrTab; SymbolTableBaseSection *SymTab; SymtabShndxSection *SymTabShndx; + VersionDefinitionSection *VerDef; }; extern InStruct In; template <class ELFT> struct InX { - static VersionDefinitionSection<ELFT> *VerDef; static VersionTableSection<ELFT> *VerSym; static VersionNeedSection<ELFT> *VerNeed; }; -template <class ELFT> VersionDefinitionSection<ELFT> *InX<ELFT>::VerDef; template <class ELFT> VersionTableSection<ELFT> *InX<ELFT>::VerSym; template <class ELFT> VersionNeedSection<ELFT> *InX<ELFT>::VerNeed; } // namespace elf diff --git a/lld/ELF/Writer.cpp b/lld/ELF/Writer.cpp index be7aa93c794..713dbd21269 100644 --- a/lld/ELF/Writer.cpp +++ b/lld/ELF/Writer.cpp @@ -323,8 +323,8 @@ template <class ELFT> static void createSyntheticSections() { Add(InX<ELFT>::VerSym); if (!Config->VersionDefinitions.empty()) { - InX<ELFT>::VerDef = make<VersionDefinitionSection<ELFT>>(); - Add(InX<ELFT>::VerDef); + In.VerDef = make<VersionDefinitionSection>(); + Add(In.VerDef); } InX<ELFT>::VerNeed = make<VersionNeedSection<ELFT>>(); @@ -1675,7 +1675,7 @@ template <class ELFT> void Writer<ELFT>::finalizeSections() { In.SymTabShndx, In.ShStrTab, In.StrTab, - InX<ELFT>::VerDef, + In.VerDef, In.DynStrTab, In.Got, In.MipsGot, |