From 676c7cd1ed0fa54f65ab5fade1b4b8b61a2968d1 Mon Sep 17 00:00:00 2001 From: Peter Collingbourne Date: Tue, 26 Apr 2016 23:52:44 +0000 Subject: [PATCH] ELF: Move code to where it is used, and related cleanups. NFC. Differential Revision: http://reviews.llvm.org/D19490 llvm-svn: 267637 --- lld/ELF/ICF.cpp | 13 ++------- lld/ELF/InputFiles.h | 5 ++++ lld/ELF/InputSection.cpp | 40 +------------------------ lld/ELF/InputSection.h | 6 ---- lld/ELF/MarkLive.cpp | 73 +++++++++++++++++++++++++++++++--------------- lld/ELF/OutputSections.cpp | 28 +++++++++--------- lld/ELF/Writer.cpp | 6 ++-- 7 files changed, 74 insertions(+), 97 deletions(-) diff --git a/lld/ELF/ICF.cpp b/lld/ELF/ICF.cpp index 0f23e64..acb36fa 100644 --- a/lld/ELF/ICF.cpp +++ b/lld/ELF/ICF.cpp @@ -93,8 +93,6 @@ private: static uint64_t getHash(InputSection *S); static bool isEligible(InputSectionBase *Sec); static std::vector *> getSections(SymbolTable *S); - static SymbolBody &getSymbol(const InputSection *Sec, - const Elf_Rel *Rel); void segregate(InputSection **Begin, InputSection **End, Comparator Eq); @@ -158,13 +156,6 @@ ICF::getSections(SymbolTable *Symtab) { return V; } -template -SymbolBody &ICF::getSymbol(const InputSection *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::variableEq(const InputSection *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; diff --git a/lld/ELF/InputFiles.h b/lld/ELF/InputFiles.h index 8776550..ca6eeb3 100644 --- a/lld/ELF/InputFiles.h +++ b/lld/ELF/InputFiles.h @@ -127,6 +127,11 @@ public: return SymbolBodies[SymbolIndex]->repl(); } + template 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 diff --git a/lld/ELF/InputSection.cpp b/lld/ELF/InputSection.cpp index b114ce72..59625ed 100644 --- a/lld/ELF/InputSection.cpp +++ b/lld/ELF/InputSection.cpp @@ -78,43 +78,6 @@ InputSectionBase::getOffset(const DefinedRegular &Sym) { } template -static DefinedRegular *getRelocTargetSym(elf::ObjectFile *File, - const typename ELFT::Rel &Rel) { - uint32_t SymIndex = Rel.getSymbol(Config->Mips64EL); - SymbolBody &B = File->getSymbolBody(SymIndex); - if (auto *D = dyn_cast>(&B)) - if (D->Section) - return D; - return nullptr; -} - -// Returns a section that Rel relocation is pointing to. -template -std::pair *, typename ELFT::uint> -InputSectionBase::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 -std::pair *, typename ELFT::uint> -InputSectionBase::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 InputSection::InputSection(elf::ObjectFile *F, const Elf_Shdr *Header) : InputSectionBase(F, Header, Base::Regular) {} @@ -153,9 +116,8 @@ void InputSection::copyRelocations(uint8_t *Buf, ArrayRef Rels) { InputSectionBase *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(Buf); Buf += sizeof(RelTy); diff --git a/lld/ELF/InputSection.h b/lld/ELF/InputSection.h index a97b504..3fd5d12 100644 --- a/lld/ELF/InputSection.h +++ b/lld/ELF/InputSection.h @@ -123,12 +123,6 @@ public: ArrayRef getSectionData() const; - // Returns a section that Rel is pointing to. Used by the garbage collector. - std::pair *, uintX_t> - getRelocTarget(const Elf_Rel &Rel) const; - std::pair *, uintX_t> - getRelocTarget(const Elf_Rela &Rel) const; - void relocate(uint8_t *Buf, uint8_t *BufEnd); std::vector Relocations; }; diff --git a/lld/ELF/MarkLive.cpp b/lld/ELF/MarkLive.cpp index b76c8b0..0d59874 100644 --- a/lld/ELF/MarkLive.cpp +++ b/lld/ELF/MarkLive.cpp @@ -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 +struct ResolvedReloc { + InputSectionBase *Sec; + typename ELFT::uint Offset; +}; + +template +static typename ELFT::uint getAddend(InputSectionBase *Sec, + const typename ELFT::Rel &Rel) { + return Target->getImplicitAddend(Sec->getSectionData().begin(), + Rel.getType(Config->Mips64EL)); +} + +template +static typename ELFT::uint getAddend(InputSectionBase *Sec, + const typename ELFT::Rela &Rel) { + return Rel.r_addend; +} + +template +static ResolvedReloc resolveReloc(InputSection *Sec, RelT &Rel) { + SymbolBody &B = Sec->getFile()->getRelocTargetSym(Rel); + auto *D = dyn_cast>(&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 -static void forEachSuccessor( - InputSection *Sec, - std::function *, typename ELFT::uint Offset)> - Fn) { +static void forEachSuccessor(InputSection *Sec, + std::function)> 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 &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 *, 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 *, 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 void elf::markLive(SymbolTable *Symtab) { typedef typename ELFT::uint uintX_t; SmallVector *, 256> Q; - auto Enqueue = [&](InputSectionBase *Sec, uintX_t Offset) { - if (!Sec) + auto Enqueue = [&](ResolvedReloc R) { + if (!R.Sec) return; - if (auto *MS = dyn_cast>(Sec)) { + if (auto *MS = dyn_cast>(R.Sec)) { std::pair *, 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 *S = dyn_cast>(Sec)) + R.Sec->Live = true; + if (InputSection *S = dyn_cast>(R.Sec)) Q.push_back(S); }; auto MarkSymbol = [&](SymbolBody *Sym) { if (Sym) if (auto *D = dyn_cast>(Sym)) - Enqueue(D->Section, D->Value); + Enqueue({D->Section, D->Value}); }; // Add GC root symbols. @@ -138,7 +163,7 @@ template void elf::markLive(SymbolTable *Symtab) { for (InputSectionBase *Sec : F->getSections()) if (Sec && Sec != &InputSection::Discarded) if (isReserved(Sec) || Script::X->shouldKeep(Sec)) - Enqueue(Sec, 0); + Enqueue({Sec, 0}); // Mark all reachable sections. while (!Q.empty()) diff --git a/lld/ELF/OutputSections.cpp b/lld/ELF/OutputSections.cpp index 811ba80..29890d5 100644 --- a/lld/ELF/OutputSections.cpp +++ b/lld/ELF/OutputSections.cpp @@ -1137,10 +1137,8 @@ void EHOutputSection::addSectionAux(EHInputSection *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 CieInfo(Entry, Personality); auto P = CieMap.insert(std::make_pair(CieInfo, Cies.size())); @@ -1152,15 +1150,19 @@ void EHOutputSection::addSectionAux(EHInputSection *S, } else { if (!HasReloc) fatal("FDE doesn't reference another section"); - InputSectionBase *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(S, Index)); - Out::EhFrameHdr->reserveFde(); - this->Header.sh_size += alignTo(Length, sizeof(uintX_t)); + SymbolBody &B = S->getFile()->getRelocTargetSym(*RelI); + auto *D = dyn_cast>(&B); + if (D && D->Section) { + InputSectionBase *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(S, Index)); + Out::EhFrameHdr->reserveFde(); + this->Header.sh_size += alignTo(Length, sizeof(uintX_t)); + } } } diff --git a/lld/ELF/Writer.cpp b/lld/ELF/Writer.cpp index fbf173c..41ec89f 100644 --- a/lld/ELF/Writer.cpp +++ b/lld/ELF/Writer.cpp @@ -361,8 +361,7 @@ void Writer::scanRelocsForThunks(const elf::ObjectFile &File, ArrayRef 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>(&Body); @@ -520,8 +519,7 @@ void Writer::scanRelocs(InputSectionBase &C, ArrayRef 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. -- 2.7.4