Add DT_REL(A)COUNT tag to .dynamic section
This patch groups relative relocations in a single block
in combrelocs mode and adds DT_RELCOUNT or DT_RELACOUNT
tag to .dynamic section
Differential revision: https://reviews.llvm.org/D23661
llvm-svn: 280210
diff --git a/lld/ELF/OutputSections.cpp b/lld/ELF/OutputSections.cpp
index 05c4fa9..37fc054 100644
--- a/lld/ELF/OutputSections.cpp
+++ b/lld/ELF/OutputSections.cpp
@@ -354,11 +354,18 @@
template <class ELFT>
void RelocationSection<ELFT>::addReloc(const DynamicReloc<ELFT> &Reloc) {
+ if (Reloc.Type == Target->RelativeRel)
+ ++NumRelativeRelocs;
Relocs.push_back(Reloc);
}
template <class ELFT, class RelTy>
static bool compRelocations(const RelTy &A, const RelTy &B) {
+ bool AIsRel = A.getType(Config->Mips64EL) == Target->RelativeRel;
+ bool BIsRel = B.getType(Config->Mips64EL) == Target->RelativeRel;
+ if (AIsRel != BIsRel)
+ return AIsRel;
+
return A.getSymbol(Config->Mips64EL) < B.getSymbol(Config->Mips64EL);
}
@@ -661,6 +668,10 @@
Add({IsRela ? DT_RELASZ : DT_RELSZ, Out<ELFT>::RelaDyn->getSize()});
Add({IsRela ? DT_RELAENT : DT_RELENT,
uintX_t(IsRela ? sizeof(Elf_Rela) : sizeof(Elf_Rel))});
+
+ size_t NumRelativeRels = Out<ELFT>::RelaDyn->getRelativeRelocCount();
+ if (Config->ZCombreloc && NumRelativeRels)
+ Add({IsRela ? DT_RELACOUNT : DT_RELCOUNT, NumRelativeRels});
}
if (Out<ELFT>::RelaPlt && Out<ELFT>::RelaPlt->hasRelocs()) {
Add({DT_JMPREL, Out<ELFT>::RelaPlt});