From 12504649dc66c0d5cfc2dccc7d3c5e65649a65f7 Mon Sep 17 00:00:00 2001 From: Rui Ueyama Date: Tue, 27 Oct 2015 21:51:13 +0000 Subject: [PATCH] ELF2: Move some code from MarkLive.cpp to InputSection.cpp. This function is useful for ICF, so move that to a common place. llvm-svn: 251455 --- lld/ELF/InputSection.cpp | 22 +++++++++++++++++++++ lld/ELF/InputSection.h | 6 ++++++ lld/ELF/MarkLive.cpp | 41 +++++++++++++--------------------------- 3 files changed, 41 insertions(+), 28 deletions(-) diff --git a/lld/ELF/InputSection.cpp b/lld/ELF/InputSection.cpp index 60b854652ab8..1528dc5853dc 100644 --- a/lld/ELF/InputSection.cpp +++ b/lld/ELF/InputSection.cpp @@ -49,6 +49,28 @@ InputSectionBase::getOffset(const Elf_Sym &Sym) { return cast>(this)->getOffset(Sym.st_value); } +// Returns a section that Rel relocation is pointing to. +template +InputSectionBase * +InputSectionBase::getRelocTarget(const Elf_Rel &Rel) { + // Global symbol + uint32_t SymIndex = Rel.getSymbol(Config->Mips64EL); + if (SymbolBody *B = File->getSymbolBody(SymIndex)) + if (auto *D = dyn_cast>(B->repl())) + return &D->Section; + // Local symbol + if (const Elf_Sym *Sym = File->getLocalSymbol(SymIndex)) + if (InputSectionBase *Sec = File->getSection(*Sym)) + return Sec; + return nullptr; +} + +template +InputSectionBase * +InputSectionBase::getRelocTarget(const Elf_Rela &Rel) { + return getRelocTarget(reinterpret_cast(Rel)); +} + template InputSection::InputSection(ObjectFile *F, const Elf_Shdr *Header) : InputSectionBase(F, Header, Base::Regular) {} diff --git a/lld/ELF/InputSection.h b/lld/ELF/InputSection.h index 36d89a7da1ae..2e245cac193e 100644 --- a/lld/ELF/InputSection.h +++ b/lld/ELF/InputSection.h @@ -24,6 +24,8 @@ template class OutputSectionBase; // This corresponds to a section of an input file. template class InputSectionBase { protected: + typedef typename llvm::object::ELFFile::Elf_Rel Elf_Rel; + typedef typename llvm::object::ELFFile::Elf_Rela Elf_Rela; typedef typename llvm::object::ELFFile::Elf_Shdr Elf_Shdr; typedef typename llvm::object::ELFFile::Elf_Sym Elf_Sym; typedef typename llvm::object::ELFFile::uintX_t uintX_t; @@ -63,6 +65,10 @@ public: uintX_t getOffset(const Elf_Sym &Sym); ArrayRef getSectionData() const; + + // Returns a section that Rel is pointing to. Used by the garbage collector. + InputSectionBase *getRelocTarget(const Elf_Rel &Rel); + InputSectionBase *getRelocTarget(const Elf_Rela &Rel); }; template diff --git a/lld/ELF/MarkLive.cpp b/lld/ELF/MarkLive.cpp index db411530a681..7e73a1fd78e6 100644 --- a/lld/ELF/MarkLive.cpp +++ b/lld/ELF/MarkLive.cpp @@ -37,40 +37,25 @@ using namespace llvm::object; using namespace lld; using namespace lld::elf2; -template -static void -doForEachSuccessor(InputSectionBase *Sec, - std::function *)> Fn, - iterator_range *> Rels) { - typedef typename ELFFile::Elf_Sym Elf_Sym; - typedef Elf_Rel_Impl RelType; - - ObjectFile *File = Sec->getFile(); - for (const RelType &RI : Rels) { - // Global symbol - uint32_t SymIndex = RI.getSymbol(Config->Mips64EL); - if (SymbolBody *B = File->getSymbolBody(SymIndex)) { - if (auto *D = dyn_cast>(B->repl())) - Fn(&D->Section); - continue; - } - // Local symbol - if (const Elf_Sym *Sym = File->getLocalSymbol(SymIndex)) - if (InputSectionBase *Sec = File->getSection(*Sym)) - Fn(Sec); - } -} - // Calls Fn for each section that Sec refers to. template static void forEachSuccessor(InputSection *Sec, std::function *)> Fn) { + typedef typename ELFFile::Elf_Rel Elf_Rel; + typedef typename ELFFile::Elf_Rela Elf_Rela; typedef typename ELFFile::Elf_Shdr Elf_Shdr; + + ELFFile &Obj = Sec->getFile()->getObj(); for (const Elf_Shdr *RelSec : Sec->RelocSections) { - if (RelSec->sh_type == SHT_RELA) - doForEachSuccessor(Sec, Fn, Sec->getFile()->getObj().relas(RelSec)); - else - doForEachSuccessor(Sec, Fn, Sec->getFile()->getObj().rels(RelSec)); + if (RelSec->sh_type == SHT_RELA) { + for (const Elf_Rela &RI : Obj.relas(RelSec)) + if (InputSectionBase *Succ = Sec->getRelocTarget(RI)) + Fn(Succ); + } else { + for (const Elf_Rel &RI : Obj.rels(RelSec)) + if (InputSectionBase *Succ = Sec->getRelocTarget(RI)) + Fn(Succ); + } } }