forked from OSchip/llvm-project
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:
parent
4633a373e0
commit
12504649dc
|
@ -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) {}
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue