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
This commit is contained in:
Rui Ueyama 2015-10-27 21:51:13 +00:00
parent 4633a373e0
commit 12504649dc
3 changed files with 41 additions and 28 deletions

View File

@ -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) {}

View File

@ -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>

View File

@ -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);
}
}
}