diff options
| author | Eugene Leviant <evgeny.leviant@gmail.com> | 2016-08-31 08:51:39 +0000 |
|---|---|---|
| committer | Eugene Leviant <evgeny.leviant@gmail.com> | 2016-08-31 08:51:39 +0000 |
| commit | aa49819162d6aa060271e99ead72e2d84f4bc29d (patch) | |
| tree | 2fd1f4fb7202a2e240422cc98da49f0e54fa6f4e /lld/ELF | |
| parent | 9503f6d2117a834a50295b14c787d0bf6c7edb1e (diff) | |
| download | bcm5719-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.cpp | 11 | ||||
| -rw-r--r-- | lld/ELF/OutputSections.h | 2 |
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; }; |

