ELF: Move code to where it is used, and related cleanups. NFC.

Differential Revision: http://reviews.llvm.org/D19490

llvm-svn: 267637
This commit is contained in:
Peter Collingbourne 2016-04-26 23:52:44 +00:00
parent d9974cc913
commit 676c7cd1ed
7 changed files with 74 additions and 97 deletions

View File

@ -93,8 +93,6 @@ private:
static uint64_t getHash(InputSection<ELFT> *S);
static bool isEligible(InputSectionBase<ELFT> *Sec);
static std::vector<InputSection<ELFT> *> getSections(SymbolTable<ELFT> *S);
static SymbolBody &getSymbol(const InputSection<ELFT> *Sec,
const Elf_Rel *Rel);
void segregate(InputSection<ELFT> **Begin, InputSection<ELFT> **End,
Comparator Eq);
@ -158,13 +156,6 @@ ICF<ELFT>::getSections(SymbolTable<ELFT> *Symtab) {
return V;
}
template <class ELFT>
SymbolBody &ICF<ELFT>::getSymbol(const InputSection<ELFT> *Sec,
const Elf_Rel *Rel) {
uint32_t SymIdx = Rel->getSymbol(Config->Mips64EL);
return Sec->File->getSymbolBody(SymIdx);
}
// All sections between Begin and End must have the same group ID before
// you call this function. This function compare sections between Begin
// and End using Eq and assign new group IDs for new groups.
@ -255,8 +246,8 @@ bool ICF<ELFT>::variableEq(const InputSection<ELFT> *A,
const RelTy *EA = RelsA.end();
const RelTy *IB = RelsB.begin();
for (; IA != EA; ++IA, ++IB) {
SymbolBody &SA = getSymbol(A, (const Elf_Rel *)IA);
SymbolBody &SB = getSymbol(B, (const Elf_Rel *)IB);
SymbolBody &SA = A->File->getRelocTargetSym(*IA);
SymbolBody &SB = B->File->getRelocTargetSym(*IB);
if (&SA == &SB)
continue;

View File

@ -127,6 +127,11 @@ public:
return SymbolBodies[SymbolIndex]->repl();
}
template <typename RelT> SymbolBody &getRelocTargetSym(const RelT &Rel) const {
uint32_t SymIndex = Rel.getSymbol(Config->Mips64EL);
return getSymbolBody(SymIndex);
}
const Elf_Shdr *getSymbolTable() const { return this->Symtab; };
// Get MIPS GP0 value defined by this file. This value represents the gp value

View File

@ -77,43 +77,6 @@ InputSectionBase<ELFT>::getOffset(const DefinedRegular<ELFT> &Sym) {
return getOffset(Sym.Value);
}
template <class ELFT>
static DefinedRegular<ELFT> *getRelocTargetSym(elf::ObjectFile<ELFT> *File,
const typename ELFT::Rel &Rel) {
uint32_t SymIndex = Rel.getSymbol(Config->Mips64EL);
SymbolBody &B = File->getSymbolBody(SymIndex);
if (auto *D = dyn_cast<DefinedRegular<ELFT>>(&B))
if (D->Section)
return D;
return nullptr;
}
// Returns a section that Rel relocation is pointing to.
template <class ELFT>
std::pair<InputSectionBase<ELFT> *, typename ELFT::uint>
InputSectionBase<ELFT>::getRelocTarget(const Elf_Rel &Rel) const {
auto *D = getRelocTargetSym(File, Rel);
if (!D)
return std::make_pair(nullptr, 0);
if (!D->isSection())
return std::make_pair(D->Section->Repl, D->Value);
const uint8_t *BufLoc = getSectionData().begin() + Rel.r_offset;
uintX_t Addend =
Target->getImplicitAddend(BufLoc, Rel.getType(Config->Mips64EL));
return std::make_pair(D->Section->Repl, D->Value + Addend);
}
template <class ELFT>
std::pair<InputSectionBase<ELFT> *, typename ELFT::uint>
InputSectionBase<ELFT>::getRelocTarget(const Elf_Rela &Rel) const {
auto *D = getRelocTargetSym(File, Rel);
if (!D)
return std::make_pair(nullptr, 0);
if (!D->isSection())
return std::make_pair(D->Section->Repl, D->Value);
return std::make_pair(D->Section->Repl, D->Value + Rel.r_addend);
}
template <class ELFT>
InputSection<ELFT>::InputSection(elf::ObjectFile<ELFT> *F,
const Elf_Shdr *Header)
@ -153,9 +116,8 @@ void InputSection<ELFT>::copyRelocations(uint8_t *Buf, ArrayRef<RelTy> Rels) {
InputSectionBase<ELFT> *RelocatedSection = getRelocatedSection();
for (const RelTy &Rel : Rels) {
uint32_t SymIndex = Rel.getSymbol(Config->Mips64EL);
uint32_t Type = Rel.getType(Config->Mips64EL);
SymbolBody &Body = this->File->getSymbolBody(SymIndex);
SymbolBody &Body = this->File->getRelocTargetSym(Rel);
RelTy *P = reinterpret_cast<RelTy *>(Buf);
Buf += sizeof(RelTy);

View File

@ -123,12 +123,6 @@ public:
ArrayRef<uint8_t> getSectionData() const;
// Returns a section that Rel is pointing to. Used by the garbage collector.
std::pair<InputSectionBase<ELFT> *, uintX_t>
getRelocTarget(const Elf_Rel &Rel) const;
std::pair<InputSectionBase<ELFT> *, uintX_t>
getRelocTarget(const Elf_Rela &Rel) const;
void relocate(uint8_t *Buf, uint8_t *BufEnd);
std::vector<Relocation> Relocations;
};

View File

@ -25,6 +25,7 @@
#include "OutputSections.h"
#include "SymbolTable.h"
#include "Symbols.h"
#include "Target.h"
#include "Writer.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/Object/ELF.h"
@ -38,31 +39,55 @@ using namespace llvm::object;
using namespace lld;
using namespace lld::elf;
// A resolved relocation. The Sec and Offset fields are set if the relocation
// was resolved to an offset within a section.
template <class ELFT>
struct ResolvedReloc {
InputSectionBase<ELFT> *Sec;
typename ELFT::uint Offset;
};
template <class ELFT>
static typename ELFT::uint getAddend(InputSectionBase<ELFT> *Sec,
const typename ELFT::Rel &Rel) {
return Target->getImplicitAddend(Sec->getSectionData().begin(),
Rel.getType(Config->Mips64EL));
}
template <class ELFT>
static typename ELFT::uint getAddend(InputSectionBase<ELFT> *Sec,
const typename ELFT::Rela &Rel) {
return Rel.r_addend;
}
template <class ELFT, class RelT>
static ResolvedReloc<ELFT> resolveReloc(InputSection<ELFT> *Sec, RelT &Rel) {
SymbolBody &B = Sec->getFile()->getRelocTargetSym(Rel);
auto *D = dyn_cast<DefinedRegular<ELFT>>(&B);
if (!D || !D->Section)
return {nullptr, 0};
typename ELFT::uint Offset = D->Value;
if (D->isSection())
Offset += getAddend(Sec, Rel);
return {D->Section->Repl, Offset};
}
// Calls Fn for each section that Sec refers to via relocations.
template <class ELFT>
static void forEachSuccessor(
InputSection<ELFT> *Sec,
std::function<void(InputSectionBase<ELFT> *, typename ELFT::uint Offset)>
Fn) {
static void forEachSuccessor(InputSection<ELFT> *Sec,
std::function<void(ResolvedReloc<ELFT>)> Fn) {
typedef typename ELFT::Rel Elf_Rel;
typedef typename ELFT::Rela Elf_Rela;
typedef typename ELFT::Shdr Elf_Shdr;
typedef typename ELFT::uint uintX_t;
ELFFile<ELFT> &Obj = Sec->getFile()->getObj();
for (const Elf_Shdr *RelSec : Sec->RelocSections) {
if (RelSec->sh_type == SHT_RELA) {
for (const Elf_Rela &RI : Obj.relas(RelSec)) {
std::pair<InputSectionBase<ELFT> *, uintX_t> P =
Sec->getRelocTarget(RI);
Fn(P.first, P.second);
}
for (const Elf_Rela &RI : Obj.relas(RelSec))
Fn(resolveReloc(Sec, RI));
} else {
for (const Elf_Rel &RI : Obj.rels(RelSec)) {
std::pair<InputSectionBase<ELFT> *, uintX_t> P =
Sec->getRelocTarget(RI);
Fn(P.first, P.second);
}
for (const Elf_Rel &RI : Obj.rels(RelSec))
Fn(resolveReloc(Sec, RI));
}
}
}
@ -97,25 +122,25 @@ template <class ELFT> void elf::markLive(SymbolTable<ELFT> *Symtab) {
typedef typename ELFT::uint uintX_t;
SmallVector<InputSection<ELFT> *, 256> Q;
auto Enqueue = [&](InputSectionBase<ELFT> *Sec, uintX_t Offset) {
if (!Sec)
auto Enqueue = [&](ResolvedReloc<ELFT> R) {
if (!R.Sec)
return;
if (auto *MS = dyn_cast<MergeInputSection<ELFT>>(Sec)) {
if (auto *MS = dyn_cast<MergeInputSection<ELFT>>(R.Sec)) {
std::pair<std::pair<uintX_t, uintX_t> *, uintX_t> T =
MS->getRangeAndSize(Offset);
MS->getRangeAndSize(R.Offset);
T.first->second = 0;
}
if (Sec->Live)
if (R.Sec->Live)
return;
Sec->Live = true;
if (InputSection<ELFT> *S = dyn_cast<InputSection<ELFT>>(Sec))
R.Sec->Live = true;
if (InputSection<ELFT> *S = dyn_cast<InputSection<ELFT>>(R.Sec))
Q.push_back(S);
};
auto MarkSymbol = [&](SymbolBody *Sym) {
if (Sym)
if (auto *D = dyn_cast<DefinedRegular<ELFT>>(Sym))
Enqueue(D->Section, D->Value);
Enqueue({D->Section, D->Value});
};
// Add GC root symbols.
@ -138,7 +163,7 @@ template <class ELFT> void elf::markLive(SymbolTable<ELFT> *Symtab) {
for (InputSectionBase<ELFT> *Sec : F->getSections())
if (Sec && Sec != &InputSection<ELFT>::Discarded)
if (isReserved(Sec) || Script<ELFT>::X->shouldKeep(Sec))
Enqueue(Sec, 0);
Enqueue({Sec, 0});
// Mark all reachable sections.
while (!Q.empty())

View File

@ -1137,10 +1137,8 @@ void EHOutputSection<ELFT>::addSectionAux(EHInputSection<ELFT> *S,
C.FdeEncoding = getFdeEncoding(D);
SymbolBody *Personality = nullptr;
if (HasReloc) {
uint32_t SymIndex = RelI->getSymbol(Config->Mips64EL);
Personality = &S->getFile()->getSymbolBody(SymIndex);
}
if (HasReloc)
Personality = &S->getFile()->getRelocTargetSym(*RelI);
std::pair<StringRef, SymbolBody *> CieInfo(Entry, Personality);
auto P = CieMap.insert(std::make_pair(CieInfo, Cies.size()));
@ -1152,15 +1150,19 @@ void EHOutputSection<ELFT>::addSectionAux(EHInputSection<ELFT> *S,
} else {
if (!HasReloc)
fatal("FDE doesn't reference another section");
InputSectionBase<ELFT> *Target = S->getRelocTarget(*RelI).first;
if (Target && Target->Live) {
uint32_t CieOffset = Offset + 4 - ID;
auto I = OffsetToIndex.find(CieOffset);
if (I == OffsetToIndex.end())
fatal("invalid CIE reference");
Cies[I->second].Fdes.push_back(EHRegion<ELFT>(S, Index));
Out<ELFT>::EhFrameHdr->reserveFde();
this->Header.sh_size += alignTo(Length, sizeof(uintX_t));
SymbolBody &B = S->getFile()->getRelocTargetSym(*RelI);
auto *D = dyn_cast<DefinedRegular<ELFT>>(&B);
if (D && D->Section) {
InputSectionBase<ELFT> *Target = D->Section->Repl;
if (Target && Target->Live) {
uint32_t CieOffset = Offset + 4 - ID;
auto I = OffsetToIndex.find(CieOffset);
if (I == OffsetToIndex.end())
fatal("invalid CIE reference");
Cies[I->second].Fdes.push_back(EHRegion<ELFT>(S, Index));
Out<ELFT>::EhFrameHdr->reserveFde();
this->Header.sh_size += alignTo(Length, sizeof(uintX_t));
}
}
}

View File

@ -361,8 +361,7 @@ void Writer<ELFT>::scanRelocsForThunks(const elf::ObjectFile<ELFT> &File,
ArrayRef<RelTy> Rels) {
for (const RelTy &RI : Rels) {
uint32_t Type = RI.getType(Config->Mips64EL);
uint32_t SymIndex = RI.getSymbol(Config->Mips64EL);
SymbolBody &Body = File.getSymbolBody(SymIndex);
SymbolBody &Body = File.getRelocTargetSym(RI);
if (Body.hasThunk() || !Target->needsThunk(Type, File, Body))
continue;
auto *D = cast<DefinedRegular<ELFT>>(&Body);
@ -520,8 +519,7 @@ void Writer<ELFT>::scanRelocs(InputSectionBase<ELFT> &C, ArrayRef<RelTy> Rels) {
const uint8_t *Buf = SectionData.begin();
for (auto I = Rels.begin(), E = Rels.end(); I != E; ++I) {
const RelTy &RI = *I;
uint32_t SymIndex = RI.getSymbol(Config->Mips64EL);
SymbolBody &Body = File.getSymbolBody(SymIndex);
SymbolBody &Body = File.getRelocTargetSym(RI);
uint32_t Type = RI.getType(Config->Mips64EL);
// Ignore "hint" relocation because it is for optional code optimization.