forked from OSchip/llvm-project
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:
parent
d9974cc913
commit
676c7cd1ed
|
@ -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;
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
|
|
@ -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())
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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.
|
||||
|
|
Loading…
Reference in New Issue