[lld] r303355 - Alternative way to detemplate GotSection.
Rafael Espindola via llvm-commits
llvm-commits at lists.llvm.org
Thu May 18 09:45:37 PDT 2017
Author: rafael
Date: Thu May 18 11:45:36 2017
New Revision: 303355
URL: http://llvm.org/viewvc/llvm-project?rev=303355&view=rev
Log:
Alternative way to detemplate GotSection.
GetSection is a template because write calls relocate.
relocate has two parts. The non alloc code really has to be a
template, as it is looking a raw input file data.
The alloc part is only a template because of getSize.
This patch folds the value of getSize early, detemplates
getRelocTargetVA and splits relocate into a templated non alloc case
and a regular function for the alloc case. This has the nice advantage
of making sure we collect all the information we need for relocations
before getting to InputSection::relocateNonAlloc.
Since we know got is alloc, it can just call the function directly and
avoid the template.
Modified:
lld/trunk/ELF/InputSection.cpp
lld/trunk/ELF/InputSection.h
lld/trunk/ELF/Relocations.cpp
lld/trunk/ELF/SyntheticSections.cpp
lld/trunk/ELF/SyntheticSections.h
lld/trunk/ELF/Writer.cpp
Modified: lld/trunk/ELF/InputSection.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/InputSection.cpp?rev=303355&r1=303354&r2=303355&view=diff
==============================================================================
--- lld/trunk/ELF/InputSection.cpp (original)
+++ lld/trunk/ELF/InputSection.cpp Thu May 18 11:45:36 2017
@@ -404,10 +404,8 @@ static uint64_t getARMStaticBase(const S
return OS->FirstInPtLoad->Addr;
}
-template <class ELFT>
-static typename ELFT::uint
-getRelocTargetVA(uint32_t Type, int64_t A, typename ELFT::uint P,
- const SymbolBody &Body, RelExpr Expr) {
+static uint64_t getRelocTargetVA(uint32_t Type, int64_t A, uint64_t P,
+ const SymbolBody &Body, RelExpr Expr) {
switch (Expr) {
case R_ABS:
case R_RELAX_GOT_PC_NOPIC:
@@ -534,7 +532,7 @@ getRelocTargetVA(uint32_t Type, int64_t
case R_NEG_TLS:
return Out::TlsPhdr->p_memsz - Body.getVA(A);
case R_SIZE:
- return Body.getSize<ELFT>() + A;
+ return A; // Body.getSize was already folded into the addend.
case R_TLSDESC:
return InX::Got->getGlobalDynAddr(Body) + A;
case R_TLSDESC_PAGE:
@@ -582,7 +580,7 @@ void InputSection::relocateNonAlloc(uint
uint64_t SymVA = 0;
if (!Sym.isTls() || Out::TlsPhdr)
SymVA = SignExtend64<sizeof(typename ELFT::uint) * 8>(
- getRelocTargetVA<ELFT>(Type, Addend, AddrLoc, Sym, R_ABS));
+ getRelocTargetVA(Type, Addend, AddrLoc, Sym, R_ABS));
Target->relocateOne(BufLoc, Type, SymVA);
}
}
@@ -593,19 +591,28 @@ template <class ELFT> elf::ObjectFile<EL
template <class ELFT>
void InputSectionBase::relocate(uint8_t *Buf, uint8_t *BufEnd) {
+ if (Flags & SHF_ALLOC)
+ relocateAlloc(Buf, BufEnd);
+ else
+ relocateNonAlloc<ELFT>(Buf, BufEnd);
+}
+
+template <class ELFT>
+void InputSectionBase::relocateNonAlloc(uint8_t *Buf, uint8_t *BufEnd) {
// scanReloc function in Writer.cpp constructs Relocations
// vector only for SHF_ALLOC'ed sections. For other sections,
// we handle relocations directly here.
- auto *IS = dyn_cast<InputSection>(this);
- if (IS && !(IS->Flags & SHF_ALLOC)) {
- if (IS->AreRelocsRela)
- IS->relocateNonAlloc<ELFT>(Buf, IS->template relas<ELFT>());
- else
- IS->relocateNonAlloc<ELFT>(Buf, IS->template rels<ELFT>());
- return;
- }
+ auto *IS = cast<InputSection>(this);
+ assert(!(IS->Flags & SHF_ALLOC));
+ if (IS->AreRelocsRela)
+ IS->relocateNonAlloc<ELFT>(Buf, IS->template relas<ELFT>());
+ else
+ IS->relocateNonAlloc<ELFT>(Buf, IS->template rels<ELFT>());
+}
- const unsigned Bits = sizeof(typename ELFT::uint) * 8;
+void InputSectionBase::relocateAlloc(uint8_t *Buf, uint8_t *BufEnd) {
+ assert(Flags & SHF_ALLOC);
+ const unsigned Bits = Config->Wordsize * 8;
for (const Relocation &Rel : Relocations) {
uint64_t Offset = getOffset(Rel.Offset);
uint8_t *BufLoc = Buf + Offset;
@@ -613,8 +620,8 @@ void InputSectionBase::relocate(uint8_t
uint64_t AddrLoc = getOutputSection()->Addr + Offset;
RelExpr Expr = Rel.Expr;
- uint64_t TargetVA = SignExtend64<Bits>(
- getRelocTargetVA<ELFT>(Type, Rel.Addend, AddrLoc, *Rel.Sym, Expr));
+ uint64_t TargetVA = SignExtend64(
+ getRelocTargetVA(Type, Rel.Addend, AddrLoc, *Rel.Sym, Expr), Bits);
switch (Expr) {
case R_RELAX_GOT_PC:
Modified: lld/trunk/ELF/InputSection.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/InputSection.h?rev=303355&r1=303354&r2=303355&view=diff
==============================================================================
--- lld/trunk/ELF/InputSection.h (original)
+++ lld/trunk/ELF/InputSection.h Thu May 18 11:45:36 2017
@@ -167,6 +167,8 @@ public:
template <class ELFT> std::string getObjMsg(uint64_t Offset);
template <class ELFT> void relocate(uint8_t *Buf, uint8_t *BufEnd);
+ void relocateAlloc(uint8_t *Buf, uint8_t *BufEnd);
+ template <class ELFT> void relocateNonAlloc(uint8_t *Buf, uint8_t *BufEnd);
std::vector<Relocation> Relocations;
Modified: lld/trunk/ELF/Relocations.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Relocations.cpp?rev=303355&r1=303354&r2=303355&view=diff
==============================================================================
--- lld/trunk/ELF/Relocations.cpp (original)
+++ lld/trunk/ELF/Relocations.cpp Thu May 18 11:45:36 2017
@@ -935,6 +935,10 @@ static void scanRelocs(InputSectionBase
bool IsConstant =
isStaticLinkTimeConstant<ELFT>(Expr, Type, Body, Sec, Rel.r_offset);
+ // The size is not going to change, so we fold it in here.
+ if (Expr == R_SIZE)
+ Addend += Body.getSize<ELFT>();
+
// If the output being produced is position independent, the final value
// is still not known. In that case we still need some help from the
// dynamic linker. We can however do better than just copying the incoming
Modified: lld/trunk/ELF/SyntheticSections.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/SyntheticSections.cpp?rev=303355&r1=303354&r2=303355&view=diff
==============================================================================
--- lld/trunk/ELF/SyntheticSections.cpp (original)
+++ lld/trunk/ELF/SyntheticSections.cpp Thu May 18 11:45:36 2017
@@ -600,7 +600,7 @@ template <class ELFT> void EhFrameSectio
}
for (EhInputSection *S : Sections)
- S->template relocate<ELFT>(Buf, nullptr);
+ S->relocateAlloc(Buf, nullptr);
// Construct .eh_frame_hdr. .eh_frame_hdr is a binary search table
// to get a FDE from an address to which FDE is applied. So here
@@ -617,16 +617,16 @@ template <class ELFT> void EhFrameSectio
}
}
-GotBaseSection::GotBaseSection()
+GotSection::GotSection()
: SyntheticSection(SHF_ALLOC | SHF_WRITE, SHT_PROGBITS,
Target->GotEntrySize, ".got") {}
-void GotBaseSection::addEntry(SymbolBody &Sym) {
+void GotSection::addEntry(SymbolBody &Sym) {
Sym.GotIndex = NumEntries;
++NumEntries;
}
-bool GotBaseSection::addDynTlsEntry(SymbolBody &Sym) {
+bool GotSection::addDynTlsEntry(SymbolBody &Sym) {
if (Sym.GlobalDynIndex != -1U)
return false;
Sym.GlobalDynIndex = NumEntries;
@@ -637,7 +637,7 @@ bool GotBaseSection::addDynTlsEntry(Symb
// Reserves TLS entries for a TLS module ID and a TLS block offset.
// In total it takes two GOT slots.
-bool GotBaseSection::addTlsIndex() {
+bool GotSection::addTlsIndex() {
if (TlsIndexOff != uint32_t(-1))
return false;
TlsIndexOff = NumEntries * Config->Wordsize;
@@ -645,27 +645,23 @@ bool GotBaseSection::addTlsIndex() {
return true;
}
-uint64_t GotBaseSection::getGlobalDynAddr(const SymbolBody &B) const {
+uint64_t GotSection::getGlobalDynAddr(const SymbolBody &B) const {
return this->getVA() + B.GlobalDynIndex * Config->Wordsize;
}
-uint64_t GotBaseSection::getGlobalDynOffset(const SymbolBody &B) const {
+uint64_t GotSection::getGlobalDynOffset(const SymbolBody &B) const {
return B.GlobalDynIndex * Config->Wordsize;
}
-void GotBaseSection::finalizeContents() {
- Size = NumEntries * Config->Wordsize;
-}
+void GotSection::finalizeContents() { Size = NumEntries * Config->Wordsize; }
-bool GotBaseSection::empty() const {
+bool GotSection::empty() const {
// If we have a relocation that is relative to GOT (such as GOTOFFREL),
// we need to emit a GOT even if it's empty.
return NumEntries == 0 && !HasGotOffRel;
}
-template <class ELFT> void GotSection<ELFT>::writeTo(uint8_t *Buf) {
- this->template relocate<ELFT>(Buf, Buf + Size);
-}
+void GotSection::writeTo(uint8_t *Buf) { relocateAlloc(Buf, Buf + Size); }
MipsGotSection::MipsGotSection()
: SyntheticSection(SHF_ALLOC | SHF_WRITE | SHF_MIPS_GPREL, SHT_PROGBITS, 16,
@@ -2242,7 +2238,7 @@ StringTableSection *InX::DynStrTab;
SymbolTableBaseSection *InX::DynSymTab;
InputSection *InX::Interp;
GdbIndexSection *InX::GdbIndex;
-GotBaseSection *InX::Got;
+GotSection *InX::Got;
GotPltSection *InX::GotPlt;
GnuHashTableSection *InX::GnuHashTab;
IgotPltSection *InX::IgotPlt;
@@ -2284,11 +2280,6 @@ template class elf::MipsReginfoSection<E
template class elf::MipsReginfoSection<ELF64LE>;
template class elf::MipsReginfoSection<ELF64BE>;
-template class elf::GotSection<ELF32LE>;
-template class elf::GotSection<ELF32BE>;
-template class elf::GotSection<ELF64LE>;
-template class elf::GotSection<ELF64BE>;
-
template class elf::DynamicSection<ELF32LE>;
template class elf::DynamicSection<ELF32BE>;
template class elf::DynamicSection<ELF64LE>;
Modified: lld/trunk/ELF/SyntheticSections.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/SyntheticSections.h?rev=303355&r1=303354&r2=303355&view=diff
==============================================================================
--- lld/trunk/ELF/SyntheticSections.h (original)
+++ lld/trunk/ELF/SyntheticSections.h Thu May 18 11:45:36 2017
@@ -104,12 +104,13 @@ private:
llvm::DenseMap<std::pair<ArrayRef<uint8_t>, SymbolBody *>, CieRecord> CieMap;
};
-class GotBaseSection : public SyntheticSection {
+class GotSection : public SyntheticSection {
public:
- GotBaseSection();
+ GotSection();
size_t getSize() const override { return Size; }
void finalizeContents() override;
bool empty() const override;
+ void writeTo(uint8_t *Buf) override;
void addEntry(SymbolBody &Sym);
bool addDynTlsEntry(SymbolBody &Sym);
@@ -130,11 +131,6 @@ protected:
uint64_t Size = 0;
};
-template <class ELFT> class GotSection final : public GotBaseSection {
-public:
- void writeTo(uint8_t *Buf) override;
-};
-
// .note.gnu.build-id section.
class BuildIdSection : public SyntheticSection {
// First 16 bytes are a header.
@@ -764,7 +760,7 @@ struct InX {
static GnuHashTableSection *GnuHashTab;
static InputSection *Interp;
static GdbIndexSection *GdbIndex;
- static GotBaseSection *Got;
+ static GotSection *Got;
static GotPltSection *GotPlt;
static IgotPltSection *IgotPlt;
static MipsGotSection *MipsGot;
Modified: lld/trunk/ELF/Writer.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Writer.cpp?rev=303355&r1=303354&r2=303355&view=diff
==============================================================================
--- lld/trunk/ELF/Writer.cpp (original)
+++ lld/trunk/ELF/Writer.cpp Thu May 18 11:45:36 2017
@@ -403,7 +403,7 @@ template <class ELFT> void Writer<ELFT>:
InX::MipsGot = make<MipsGotSection>();
Add(InX::MipsGot);
} else {
- InX::Got = make<GotSection<ELFT>>();
+ InX::Got = make<GotSection>();
Add(InX::Got);
}
More information about the llvm-commits
mailing list