forked from OSchip/llvm-project
[ELF] Refactor PltSection and IPltSection into PltSection [NFC]
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
This commit is contained in:
parent
28239b166f
commit
f09245a689
|
@ -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);
|
||||
|
@ -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>
|
||||
|
@ -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>;
|
||||
|
|
|
@ -234,7 +234,7 @@ private:
|
|||
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.
|
||||
|
@ -461,25 +461,13 @@ private:
|
|||
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);
|
||||
|
@ -487,7 +475,12 @@ public:
|
|||
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>
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
|
|
@ -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) {
|
||||
|
|
Loading…
Reference in New Issue