diff options
Diffstat (limited to 'lld/ELF/OutputSections.cpp')
-rw-r--r-- | lld/ELF/OutputSections.cpp | 96 |
1 files changed, 8 insertions, 88 deletions
diff --git a/lld/ELF/OutputSections.cpp b/lld/ELF/OutputSections.cpp index 774860294db..040657a6b81 100644 --- a/lld/ELF/OutputSections.cpp +++ b/lld/ELF/OutputSections.cpp @@ -591,11 +591,6 @@ void GnuHashTableSection<ELFT>::addSymbols( V.push_back({Sym.Body, Sym.STName}); } -// Returns the number of version definition entries. Because the first entry -// is for the version definition itself, it is the number of versioned symbols -// plus one. Note that we don't support multiple versions yet. -static unsigned getVerDefNum() { return Config->SymbolVersions.size() + 1; } - template <class ELFT> DynamicSection<ELFT>::DynamicSection() : OutputSectionBase<ELFT>(".dynamic", SHT_DYNAMIC, SHF_ALLOC | SHF_WRITE) { @@ -698,16 +693,10 @@ template <class ELFT> void DynamicSection<ELFT>::finalize() { if (!Config->Entry.empty()) Add({DT_DEBUG, (uint64_t)0}); - bool HasVerNeed = Out<ELFT>::VerNeed->getNeedNum() != 0; - if (HasVerNeed || Out<ELFT>::VerDef) + if (size_t NeedNum = Out<ELFT>::VerNeed->getNeedNum()) { Add({DT_VERSYM, Out<ELFT>::VerSym}); - if (Out<ELFT>::VerDef) { - Add({DT_VERDEF, Out<ELFT>::VerDef}); - Add({DT_VERDEFNUM, getVerDefNum()}); - } - if (HasVerNeed) { Add({DT_VERNEED, Out<ELFT>::VerNeed}); - Add({DT_VERNEEDNUM, Out<ELFT>::VerNeed->getNeedNum()}); + Add({DT_VERNEEDNUM, NeedNum}); } if (Config->EMachine == EM_MIPS) { @@ -1444,68 +1433,6 @@ SymbolTableSection<ELFT>::getOutputSection(SymbolBody *Sym) { } template <class ELFT> -VersionDefinitionSection<ELFT>::VersionDefinitionSection() - : OutputSectionBase<ELFT>(".gnu.version_d", SHT_GNU_verdef, SHF_ALLOC) {} - -static StringRef getFileDefName() { - if (!Config->SoName.empty()) - return Config->SoName; - return Config->OutputFile; -} - -template <class ELFT> void VersionDefinitionSection<ELFT>::finalize() { - FileDefNameOff = Out<ELFT>::DynStrTab->addString(getFileDefName()); - for (Version &V : Config->SymbolVersions) - V.NameOff = Out<ELFT>::DynStrTab->addString(V.Name); - - this->Header.sh_size = - (sizeof(Elf_Verdef) + sizeof(Elf_Verdaux)) * getVerDefNum(); - this->Header.sh_link = Out<ELFT>::DynStrTab->SectionIndex; - this->Header.sh_addralign = sizeof(uint32_t); - - // sh_info should be set to the number of definitions. This fact is missed in - // documentation, but confirmed by binutils community: - // https://sourceware.org/ml/binutils/2014-11/msg00355.html - this->Header.sh_info = getVerDefNum(); -} - -template <class Elf_Verdef, class Elf_Verdaux> -static void writeDefinition(Elf_Verdef *&Verdef, Elf_Verdaux *&Verdaux, - uint32_t Flags, uint32_t Index, StringRef Name, - size_t StrTabOffset) { - Verdef->vd_version = 1; - Verdef->vd_cnt = 1; - Verdef->vd_aux = - reinterpret_cast<char *>(Verdaux) - reinterpret_cast<char *>(Verdef); - Verdef->vd_next = sizeof(Elf_Verdef); - - Verdef->vd_flags = Flags; - Verdef->vd_ndx = Index; - Verdef->vd_hash = hashSysv(Name); - ++Verdef; - - Verdaux->vda_name = StrTabOffset; - Verdaux->vda_next = 0; - ++Verdaux; -} - -template <class ELFT> -void VersionDefinitionSection<ELFT>::writeTo(uint8_t *Buf) { - Elf_Verdef *Verdef = reinterpret_cast<Elf_Verdef *>(Buf); - Elf_Verdaux *Verdaux = - reinterpret_cast<Elf_Verdaux *>(Verdef + getVerDefNum()); - - writeDefinition(Verdef, Verdaux, VER_FLG_BASE, 1, getFileDefName(), - FileDefNameOff); - - uint32_t I = 2; - for (Version &V : Config->SymbolVersions) - writeDefinition(Verdef, Verdaux, 0 /* Flags */, I++, V.Name, V.NameOff); - - Verdef[-1].vd_next = 0; -} - -template <class ELFT> VersionTableSection<ELFT>::VersionTableSection() : OutputSectionBase<ELFT>(".gnu.version", SHT_GNU_versym, SHF_ALLOC) { this->Header.sh_addralign = sizeof(uint16_t); @@ -1524,7 +1451,10 @@ template <class ELFT> void VersionTableSection<ELFT>::writeTo(uint8_t *Buf) { auto *OutVersym = reinterpret_cast<Elf_Versym *>(Buf) + 1; for (const std::pair<SymbolBody *, size_t> &P : Out<ELFT>::DynSymTab->getSymbols()) { - OutVersym->vs_index = P.first->symbol()->VersionId; + if (auto *SS = dyn_cast<SharedSymbol<ELFT>>(P.first)) + OutVersym->vs_index = SS->VersionId; + else + OutVersym->vs_index = VER_NDX_GLOBAL; ++OutVersym; } } @@ -1533,17 +1463,12 @@ template <class ELFT> VersionNeedSection<ELFT>::VersionNeedSection() : OutputSectionBase<ELFT>(".gnu.version_r", SHT_GNU_verneed, SHF_ALLOC) { this->Header.sh_addralign = sizeof(uint32_t); - - // Identifiers in verneed section start at 2 because 0 and 1 are reserved - // for VER_NDX_LOCAL and VER_NDX_GLOBAL. - // First identifiers are reserved by verdef section if it exist. - NextIndex = getVerDefNum() + 1; } template <class ELFT> void VersionNeedSection<ELFT>::addSymbol(SharedSymbol<ELFT> *SS) { if (!SS->Verdef) { - SS->symbol()->VersionId = VER_NDX_GLOBAL; + SS->VersionId = VER_NDX_GLOBAL; return; } SharedFile<ELFT> *F = SS->File; @@ -1561,7 +1486,7 @@ void VersionNeedSection<ELFT>::addSymbol(SharedSymbol<ELFT> *SS) { SS->File->getStringTable().data() + SS->Verdef->getAux()->vda_name); NV.Index = NextIndex++; } - SS->symbol()->VersionId = NV.Index; + SS->VersionId = NV.Index; } template <class ELFT> void VersionNeedSection<ELFT>::writeTo(uint8_t *Buf) { @@ -1817,11 +1742,6 @@ template class VersionNeedSection<ELF32BE>; template class VersionNeedSection<ELF64LE>; template class VersionNeedSection<ELF64BE>; -template class VersionDefinitionSection<ELF32LE>; -template class VersionDefinitionSection<ELF32BE>; -template class VersionDefinitionSection<ELF64LE>; -template class VersionDefinitionSection<ELF64BE>; - template class BuildIdSection<ELF32LE>; template class BuildIdSection<ELF32BE>; template class BuildIdSection<ELF64LE>; |