summaryrefslogtreecommitdiffstats
path: root/lld/ELF
diff options
context:
space:
mode:
authorEugene Leviant <evgeny.leviant@gmail.com>2016-08-31 08:51:39 +0000
committerEugene Leviant <evgeny.leviant@gmail.com>2016-08-31 08:51:39 +0000
commitaa49819162d6aa060271e99ead72e2d84f4bc29d (patch)
tree2fd1f4fb7202a2e240422cc98da49f0e54fa6f4e /lld/ELF
parent9503f6d2117a834a50295b14c787d0bf6c7edb1e (diff)
downloadbcm5719-llvm-aa49819162d6aa060271e99ead72e2d84f4bc29d.tar.gz
bcm5719-llvm-aa49819162d6aa060271e99ead72e2d84f4bc29d.zip
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
Diffstat (limited to 'lld/ELF')
-rw-r--r--lld/ELF/OutputSections.cpp11
-rw-r--r--lld/ELF/OutputSections.h2
2 files changed, 13 insertions, 0 deletions
diff --git a/lld/ELF/OutputSections.cpp b/lld/ELF/OutputSections.cpp
index 05c4fa903a7..37fc0545206 100644
--- a/lld/ELF/OutputSections.cpp
+++ b/lld/ELF/OutputSections.cpp
@@ -354,11 +354,18 @@ RelocationSection<ELFT>::RelocationSection(StringRef Name, bool Sort)
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 @@ template <class ELFT> void DynamicSection<ELFT>::finalize() {
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});
diff --git a/lld/ELF/OutputSections.h b/lld/ELF/OutputSections.h
index 213a5211717..b350bef1afb 100644
--- a/lld/ELF/OutputSections.h
+++ b/lld/ELF/OutputSections.h
@@ -377,10 +377,12 @@ public:
void writeTo(uint8_t *Buf) override;
bool hasRelocs() const { return !Relocs.empty(); }
typename Base::Kind getKind() const override { return Base::Reloc; }
+ size_t getRelativeRelocCount() const { return NumRelativeRelocs; }
static bool classof(const Base *B) { return B->getKind() == Base::Reloc; }
private:
bool Sort;
+ size_t NumRelativeRelocs = 0;
std::vector<DynamicReloc<ELFT>> Relocs;
};
OpenPOWER on IntegriCloud