Skip to content

Commit

Permalink
[ELF] Refactor PltSection and IPltSection into PltSection [NFC]
Browse files Browse the repository at this point in the history
    
Much of the code in PltSection and IPltSection is similar, we identify
the IPlt by a HeaderSize of 0 and alter our behaviour in the member
functions appropriately:
-Iplt does not have a header
-Iplt always follows after the Plt
    
Differential Revision: https://reviews.llvm.org/D29664

llvm-svn: 294579
  • Loading branch information
smithp35 committed Feb 9, 2017
1 parent 28239b1 commit f09245a
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 75 deletions.
76 changes: 24 additions & 52 deletions lld/ELF/SyntheticSections.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1434,19 +1434,23 @@ template <class ELFT> void HashTableSection<ELFT>::writeTo(uint8_t *Buf) {
}

template <class ELFT>
PltSection<ELFT>::PltSection()
PltSection<ELFT>::PltSection(size_t S)
: SyntheticSection<ELFT>(SHF_ALLOC | SHF_EXECINSTR, SHT_PROGBITS, 16,
".plt") {}
".plt"),
HeaderSize(S) {}

template <class ELFT> void PltSection<ELFT>::writeTo(uint8_t *Buf) {
// At beginning of PLT, we have code to call the dynamic linker
// to resolve dynsyms at runtime. Write such code.
Target->writePltHeader(Buf);
size_t Off = Target->PltHeaderSize;
// At beginning of PLT but not the IPLT, we have code to call the dynamic
// linker to resolve dynsyms at runtime. Write such code.
if (HeaderSize != 0)
Target->writePltHeader(Buf);
size_t Off = HeaderSize;
// The IPlt is immediately after the Plt, account for this in RelOff
unsigned PltOff = getPltRelocOff();

for (auto &I : Entries) {
const SymbolBody *B = I.first;
unsigned RelOff = I.second;
unsigned RelOff = I.second + PltOff;
uint64_t Got = B->getGotPltVA<ELFT>();
uint64_t Plt = this->getVA() + Off;
Target->writePlt(Buf + Off, Got, Plt, B->PltIndex, RelOff);
Expand All @@ -1456,61 +1460,34 @@ template <class ELFT> void PltSection<ELFT>::writeTo(uint8_t *Buf) {

template <class ELFT> void PltSection<ELFT>::addEntry(SymbolBody &Sym) {
Sym.PltIndex = Entries.size();
unsigned RelOff = In<ELFT>::RelaPlt->getRelocOffset();
RelocationSection<ELFT> *PltRelocSection = In<ELFT>::RelaPlt;
if (HeaderSize == 0) {
PltRelocSection = In<ELFT>::RelaIplt;
Sym.IsInIplt = true;
}
unsigned RelOff = PltRelocSection->getRelocOffset();
Entries.push_back(std::make_pair(&Sym, RelOff));
}

template <class ELFT> size_t PltSection<ELFT>::getSize() const {
return Target->PltHeaderSize + Entries.size() * Target->PltEntrySize;
return HeaderSize + Entries.size() * Target->PltEntrySize;
}

// Some architectures such as additional symbols in the PLT section. For
// example ARM uses mapping symbols to aid disassembly
template <class ELFT> void PltSection<ELFT>::addSymbols() {
Target->addPltHeaderSymbols(this);
size_t Off = Target->PltHeaderSize;
// The PLT may have symbols defined for the Header, the IPLT has no header
if (HeaderSize != 0)
Target->addPltHeaderSymbols(this);
size_t Off = HeaderSize;
for (size_t I = 0; I < Entries.size(); ++I) {
Target->addPltSymbols(this, Off);
Off += Target->PltEntrySize;
}
}

template <class ELFT>
IpltSection<ELFT>::IpltSection()
: SyntheticSection<ELFT>(SHF_ALLOC | SHF_EXECINSTR, SHT_PROGBITS, 16,
".plt") {}

template <class ELFT> void IpltSection<ELFT>::writeTo(uint8_t *Buf) {
// The IRelative relocations do not support lazy binding so no header is
// needed
size_t Off = 0;
for (auto &I : Entries) {
const SymbolBody *B = I.first;
unsigned RelOff = I.second + In<ELFT>::Plt->getSize();
uint64_t Got = B->getGotPltVA<ELFT>();
uint64_t Plt = this->getVA() + Off;
Target->writePlt(Buf + Off, Got, Plt, B->PltIndex, RelOff);
Off += Target->PltEntrySize;
}
}

template <class ELFT> void IpltSection<ELFT>::addEntry(SymbolBody &Sym) {
Sym.PltIndex = Entries.size();
Sym.IsInIplt = true;
unsigned RelOff = In<ELFT>::RelaIplt->getRelocOffset();
Entries.push_back(std::make_pair(&Sym, RelOff));
}

template <class ELFT> size_t IpltSection<ELFT>::getSize() const {
return Entries.size() * Target->PltEntrySize;
}

template <class ELFT> void IpltSection<ELFT>::addSymbols() {
size_t Off = 0;
for (size_t I = 0; I < Entries.size(); ++I) {
Target->addPltSymbols(this, Off);
Off += Target->PltEntrySize;
}
template <class ELFT> unsigned PltSection<ELFT>::getPltRelocOff() const {
return (HeaderSize == 0) ? In<ELFT>::Plt->getSize() : 0;
}

template <class ELFT>
Expand Down Expand Up @@ -2118,11 +2095,6 @@ template class elf::PltSection<ELF32BE>;
template class elf::PltSection<ELF64LE>;
template class elf::PltSection<ELF64BE>;

template class elf::IpltSection<ELF32LE>;
template class elf::IpltSection<ELF32BE>;
template class elf::IpltSection<ELF64LE>;
template class elf::IpltSection<ELF64BE>;

template class elf::GdbIndexSection<ELF32LE>;
template class elf::GdbIndexSection<ELF32BE>;
template class elf::GdbIndexSection<ELF64LE>;
Expand Down
35 changes: 14 additions & 21 deletions lld/ELF/SyntheticSections.h
Original file line number Diff line number Diff line change
Expand Up @@ -234,7 +234,7 @@ class GotPltSection final : public SyntheticSection<ELFT> {
std::vector<const SymbolBody *> Entries;
};

// The IgotPltSection is a Got associated with the IpltSection for GNU Ifunc
// The IgotPltSection is a Got associated with the PltSection for GNU Ifunc
// Symbols that will be relocated by Target->IRelativeRel.
// On most Targets the IgotPltSection will immediately follow the GotPltSection
// on ARM the IgotPltSection will immediately follow the GotSection.
Expand Down Expand Up @@ -461,33 +461,26 @@ class HashTableSection final : public SyntheticSection<ELFT> {
size_t Size = 0;
};

template <class ELFT> class PltSection final : public SyntheticSection<ELFT> {
// The PltSection is used for both the Plt and Iplt. The former always has a
// header as its first entry that is used at run-time to resolve lazy binding.
// The latter is used for GNU Ifunc symbols, that will be subject to a
// Target->IRelativeRel.
template <class ELFT> class PltSection : public SyntheticSection<ELFT> {
public:
PltSection();
void writeTo(uint8_t *Buf) override;
size_t getSize() const override;
void addEntry(SymbolBody &Sym);
bool empty() const override { return Entries.empty(); }
void addSymbols();

private:
std::vector<std::pair<const SymbolBody *, unsigned>> Entries;
};

// The IpltSection is a variant of Plt for recording entries for GNU Ifunc
// symbols that will be subject to a Target->IRelativeRel
// The IpltSection immediately follows the Plt section in the Output Section
template <class ELFT> class IpltSection final : public SyntheticSection<ELFT> {
public:
IpltSection();
PltSection(size_t HeaderSize);
void writeTo(uint8_t *Buf) override;
size_t getSize() const override;
void addEntry(SymbolBody &Sym);
bool empty() const override { return Entries.empty(); }
void addSymbols();

private:
void writeHeader(uint8_t *Buf){};
void addHeaderSymbols(){};
unsigned getPltRelocOff() const;
std::vector<std::pair<const SymbolBody *, unsigned>> Entries;
// Iplt always has HeaderSize of 0, the Plt HeaderSize is always non-zero
size_t HeaderSize;
};

template <class ELFT>
Expand Down Expand Up @@ -777,7 +770,7 @@ template <class ELFT> struct In {
static InputSection<ELFT> *Interp;
static MipsRldMapSection<ELFT> *MipsRldMap;
static PltSection<ELFT> *Plt;
static IpltSection<ELFT> *Iplt;
static PltSection<ELFT> *Iplt;
static RelocationSection<ELFT> *RelaDyn;
static RelocationSection<ELFT> *RelaPlt;
static RelocationSection<ELFT> *RelaIplt;
Expand Down Expand Up @@ -806,7 +799,7 @@ template <class ELFT> HashTableSection<ELFT> *In<ELFT>::HashTab;
template <class ELFT> InputSection<ELFT> *In<ELFT>::Interp;
template <class ELFT> MipsRldMapSection<ELFT> *In<ELFT>::MipsRldMap;
template <class ELFT> PltSection<ELFT> *In<ELFT>::Plt;
template <class ELFT> IpltSection<ELFT> *In<ELFT>::Iplt;
template <class ELFT> PltSection<ELFT> *In<ELFT>::Iplt;
template <class ELFT> RelocationSection<ELFT> *In<ELFT>::RelaDyn;
template <class ELFT> RelocationSection<ELFT> *In<ELFT>::RelaPlt;
template <class ELFT> RelocationSection<ELFT> *In<ELFT>::RelaIplt;
Expand Down
4 changes: 2 additions & 2 deletions lld/ELF/Writer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -426,9 +426,9 @@ template <class ELFT> void Writer<ELFT>::createSyntheticSections() {
false /*Sort*/);
Add(In<ELFT>::RelaIplt);

In<ELFT>::Plt = make<PltSection<ELFT>>();
In<ELFT>::Plt = make<PltSection<ELFT>>(Target->PltHeaderSize);
Add(In<ELFT>::Plt);
In<ELFT>::Iplt = make<IpltSection<ELFT>>();
In<ELFT>::Iplt = make<PltSection<ELFT>>(0);
Add(In<ELFT>::Iplt);

if (Config->EhFrameHdr) {
Expand Down

0 comments on commit f09245a

Please sign in to comment.