diff options
| author | Rui Ueyama <ruiu@google.com> | 2015-10-27 21:51:13 +0000 |
|---|---|---|
| committer | Rui Ueyama <ruiu@google.com> | 2015-10-27 21:51:13 +0000 |
| commit | 12504649dc66c0d5cfc2dccc7d3c5e65649a65f7 (patch) | |
| tree | c9f9317a00b9219d2aa687aeb4acce85d43f65f3 | |
| parent | 4633a373e05d6268cd856f705a6346766af46cd8 (diff) | |
| download | bcm5719-llvm-12504649dc66c0d5cfc2dccc7d3c5e65649a65f7.tar.gz bcm5719-llvm-12504649dc66c0d5cfc2dccc7d3c5e65649a65f7.zip | |
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
| -rw-r--r-- | lld/ELF/InputSection.cpp | 22 | ||||
| -rw-r--r-- | lld/ELF/InputSection.h | 6 | ||||
| -rw-r--r-- | 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 60b854652ab..1528dc5853d 100644 --- a/lld/ELF/InputSection.cpp +++ b/lld/ELF/InputSection.cpp @@ -49,6 +49,28 @@ InputSectionBase<ELFT>::getOffset(const Elf_Sym &Sym) { return cast<MergeInputSection<ELFT>>(this)->getOffset(Sym.st_value); } +// Returns a section that Rel relocation is pointing to. +template <class ELFT> +InputSectionBase<ELFT> * +InputSectionBase<ELFT>::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<DefinedRegular<ELFT>>(B->repl())) + return &D->Section; + // Local symbol + if (const Elf_Sym *Sym = File->getLocalSymbol(SymIndex)) + if (InputSectionBase<ELFT> *Sec = File->getSection(*Sym)) + return Sec; + return nullptr; +} + +template <class ELFT> +InputSectionBase<ELFT> * +InputSectionBase<ELFT>::getRelocTarget(const Elf_Rela &Rel) { + return getRelocTarget(reinterpret_cast<const Elf_Rel &>(Rel)); +} + template <class ELFT> InputSection<ELFT>::InputSection(ObjectFile<ELFT> *F, const Elf_Shdr *Header) : InputSectionBase<ELFT>(F, Header, Base::Regular) {} diff --git a/lld/ELF/InputSection.h b/lld/ELF/InputSection.h index 36d89a7da1a..2e245cac193 100644 --- a/lld/ELF/InputSection.h +++ b/lld/ELF/InputSection.h @@ -24,6 +24,8 @@ template <class ELFT> class OutputSectionBase; // This corresponds to a section of an input file. template <class ELFT> class InputSectionBase { protected: + typedef typename llvm::object::ELFFile<ELFT>::Elf_Rel Elf_Rel; + typedef typename llvm::object::ELFFile<ELFT>::Elf_Rela Elf_Rela; typedef typename llvm::object::ELFFile<ELFT>::Elf_Shdr Elf_Shdr; typedef typename llvm::object::ELFFile<ELFT>::Elf_Sym Elf_Sym; typedef typename llvm::object::ELFFile<ELFT>::uintX_t uintX_t; @@ -63,6 +65,10 @@ public: uintX_t getOffset(const Elf_Sym &Sym); ArrayRef<uint8_t> getSectionData() const; + + // Returns a section that Rel is pointing to. Used by the garbage collector. + InputSectionBase<ELFT> *getRelocTarget(const Elf_Rel &Rel); + InputSectionBase<ELFT> *getRelocTarget(const Elf_Rela &Rel); }; template <class ELFT> diff --git a/lld/ELF/MarkLive.cpp b/lld/ELF/MarkLive.cpp index db411530a68..7e73a1fd78e 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 <class ELFT, bool isRela> -static void -doForEachSuccessor(InputSectionBase<ELFT> *Sec, - std::function<void(InputSectionBase<ELFT> *)> Fn, - iterator_range<const Elf_Rel_Impl<ELFT, isRela> *> Rels) { - typedef typename ELFFile<ELFT>::Elf_Sym Elf_Sym; - typedef Elf_Rel_Impl<ELFT, isRela> RelType; - - ObjectFile<ELFT> *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<DefinedRegular<ELFT>>(B->repl())) - Fn(&D->Section); - continue; - } - // Local symbol - if (const Elf_Sym *Sym = File->getLocalSymbol(SymIndex)) - if (InputSectionBase<ELFT> *Sec = File->getSection(*Sym)) - Fn(Sec); - } -} - // Calls Fn for each section that Sec refers to. template <class ELFT> static void forEachSuccessor(InputSection<ELFT> *Sec, std::function<void(InputSectionBase<ELFT> *)> Fn) { + typedef typename ELFFile<ELFT>::Elf_Rel Elf_Rel; + typedef typename ELFFile<ELFT>::Elf_Rela Elf_Rela; typedef typename ELFFile<ELFT>::Elf_Shdr Elf_Shdr; + + ELFFile<ELFT> &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<ELFT> *Succ = Sec->getRelocTarget(RI)) + Fn(Succ); + } else { + for (const Elf_Rel &RI : Obj.rels(RelSec)) + if (InputSectionBase<ELFT> *Succ = Sec->getRelocTarget(RI)) + Fn(Succ); + } } } |

