[ELF] Convert PltSection to input section

Differential revision: https://reviews.llvm.org/D26842

llvm-svn: 287346
This commit is contained in:
Eugene Leviant 2016-11-18 14:35:03 +00:00
parent df613198c0
commit ff23d3e741
8 changed files with 62 additions and 70 deletions

View File

@ -108,38 +108,6 @@ template <class ELFT> void GdbIndexSection<ELFT>::writeTo(uint8_t *Buf) {
}
}
template <class ELFT>
PltSection<ELFT>::PltSection()
: OutputSectionBase(".plt", SHT_PROGBITS, SHF_ALLOC | SHF_EXECINSTR) {
this->Addralign = 16;
}
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;
for (auto &I : Entries) {
const SymbolBody *B = I.first;
unsigned RelOff = I.second;
uint64_t Got = B->getGotPltVA<ELFT>();
uint64_t Plt = this->Addr + Off;
Target->writePlt(Buf + Off, Got, Plt, B->PltIndex, RelOff);
Off += Target->PltEntrySize;
}
}
template <class ELFT> void PltSection<ELFT>::addEntry(SymbolBody &Sym) {
Sym.PltIndex = Entries.size();
unsigned RelOff = In<ELFT>::RelaPlt->getRelocOffset();
Entries.push_back(std::make_pair(&Sym, RelOff));
}
template <class ELFT> void PltSection<ELFT>::finalize() {
this->Size = Target->PltHeaderSize + Entries.size() * Target->PltEntrySize;
}
// Returns the number of version definition entries. Because the first entry
// is for the version definition itself, it is the number of versioned symbols
// plus one. Note that we don't support multiple versions yet.
@ -894,11 +862,6 @@ template class EhFrameHeader<ELF32BE>;
template class EhFrameHeader<ELF64LE>;
template class EhFrameHeader<ELF64BE>;
template class PltSection<ELF32LE>;
template class PltSection<ELF32BE>;
template class PltSection<ELF64LE>;
template class PltSection<ELF64BE>;
template class OutputSection<ELF32LE>;
template class OutputSection<ELF32BE>;
template class OutputSection<ELF64LE>;

View File

@ -45,7 +45,6 @@ public:
EHFrame,
EHFrameHdr,
Merge,
Plt,
Regular,
VersDef,
VersNeed,
@ -130,24 +129,6 @@ private:
uint32_t CuTypesOffset;
};
template <class ELFT> class PltSection final : public OutputSectionBase {
typedef typename ELFT::uint uintX_t;
public:
PltSection();
void finalize() override;
void writeTo(uint8_t *Buf) override;
void addEntry(SymbolBody &Sym);
bool empty() const { return Entries.empty(); }
Kind getKind() const override { return Plt; }
static bool classof(const OutputSectionBase *B) {
return B->getKind() == Plt;
}
private:
std::vector<std::pair<const SymbolBody *, unsigned>> Entries;
};
// For more information about .gnu.version and .gnu.version_r see:
// https://www.akkadia.org/drepper/symbol-versioning
@ -362,7 +343,6 @@ template <class ELFT> struct Out {
static OutputSection<ELFT> *MipsRldMap;
static OutputSectionBase *Opd;
static uint8_t *OpdBuf;
static PltSection<ELFT> *Plt;
static VersionDefinitionSection<ELFT> *VerDef;
static VersionTableSection<ELFT> *VerSym;
static VersionNeedSection<ELFT> *VerNeed;
@ -416,7 +396,6 @@ template <class ELFT> OutputSection<ELFT> *Out<ELFT>::Bss;
template <class ELFT> OutputSection<ELFT> *Out<ELFT>::MipsRldMap;
template <class ELFT> OutputSectionBase *Out<ELFT>::Opd;
template <class ELFT> uint8_t *Out<ELFT>::OpdBuf;
template <class ELFT> PltSection<ELFT> *Out<ELFT>::Plt;
template <class ELFT> VersionDefinitionSection<ELFT> *Out<ELFT>::VerDef;
template <class ELFT> VersionTableSection<ELFT> *Out<ELFT>::VerSym;
template <class ELFT> VersionNeedSection<ELFT> *Out<ELFT>::VerNeed;

View File

@ -743,7 +743,7 @@ static void scanRelocs(InputSectionBase<ELFT> &C, ArrayRef<RelTy> Rels) {
if (needsPlt(Expr)) {
if (Body.isInPlt())
continue;
Out<ELFT>::Plt->addEntry(Body);
In<ELFT>::Plt->addEntry(Body);
uint32_t Rel;
if (Body.isGnuIFunc() && !Preemptible)

View File

@ -167,7 +167,7 @@ template <class ELFT> typename ELFT::uint SymbolBody::getGotPltOffset() const {
}
template <class ELFT> typename ELFT::uint SymbolBody::getPltVA() const {
return Out<ELFT>::Plt->Addr + Target->PltHeaderSize +
return In<ELFT>::Plt->getVA() + Target->PltHeaderSize +
PltIndex * Target->PltEntrySize;
}

View File

@ -1329,6 +1329,37 @@ template <class ELFT> void HashTableSection<ELFT>::writeTo(uint8_t *Buf) {
}
}
template <class ELFT>
PltSection<ELFT>::PltSection()
: SyntheticSection<ELFT>(SHF_ALLOC | SHF_EXECINSTR, SHT_PROGBITS, 16,
".plt") {}
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;
for (auto &I : Entries) {
const SymbolBody *B = I.first;
unsigned RelOff = I.second;
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 PltSection<ELFT>::addEntry(SymbolBody &Sym) {
Sym.PltIndex = Entries.size();
unsigned RelOff = In<ELFT>::RelaPlt->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;
}
template InputSection<ELF32LE> *elf::createCommonSection();
template InputSection<ELF32BE> *elf::createCommonSection();
template InputSection<ELF64LE> *elf::createCommonSection();
@ -1433,3 +1464,8 @@ template class elf::HashTableSection<ELF32LE>;
template class elf::HashTableSection<ELF32BE>;
template class elf::HashTableSection<ELF64LE>;
template class elf::HashTableSection<ELF64BE>;
template class elf::PltSection<ELF32LE>;
template class elf::PltSection<ELF32BE>;
template class elf::PltSection<ELF64LE>;
template class elf::PltSection<ELF64BE>;

View File

@ -490,6 +490,18 @@ private:
size_t Size = 0;
};
template <class ELFT> class PltSection final : public SyntheticSection<ELFT> {
public:
PltSection();
void writeTo(uint8_t *Buf) override;
size_t getSize() const override;
void addEntry(SymbolBody &Sym);
bool empty() const { return Entries.empty(); }
private:
std::vector<std::pair<const SymbolBody *, unsigned>> Entries;
};
template <class ELFT> InputSection<ELFT> *createCommonSection();
template <class ELFT> InputSection<ELFT> *createInterpSection();
template <class ELFT> MergeInputSection<ELFT> *createCommentSection();
@ -510,6 +522,7 @@ template <class ELFT> struct In {
static MipsAbiFlagsSection<ELFT> *MipsAbiFlags;
static MipsOptionsSection<ELFT> *MipsOptions;
static MipsReginfoSection<ELFT> *MipsReginfo;
static PltSection<ELFT> *Plt;
static RelocationSection<ELFT> *RelaDyn;
static RelocationSection<ELFT> *RelaPlt;
static StringTableSection<ELFT> *ShStrTab;
@ -531,6 +544,7 @@ template <class ELFT> InputSection<ELFT> *In<ELFT>::Interp;
template <class ELFT> MipsAbiFlagsSection<ELFT> *In<ELFT>::MipsAbiFlags;
template <class ELFT> MipsOptionsSection<ELFT> *In<ELFT>::MipsOptions;
template <class ELFT> MipsReginfoSection<ELFT> *In<ELFT>::MipsReginfo;
template <class ELFT> PltSection<ELFT> *In<ELFT>::Plt;
template <class ELFT> RelocationSection<ELFT> *In<ELFT>::RelaDyn;
template <class ELFT> RelocationSection<ELFT> *In<ELFT>::RelaPlt;
template <class ELFT> StringTableSection<ELFT> *In<ELFT>::ShStrTab;

View File

@ -615,7 +615,7 @@ void X86_64TargetInfo<ELFT>::writePltHeader(uint8_t *Buf) const {
};
memcpy(Buf, PltData, sizeof(PltData));
uint64_t Got = In<ELFT>::GotPlt->getVA();
uint64_t Plt = Out<ELFT>::Plt->Addr;
uint64_t Plt = In<ELFT>::Plt->getVA();
write32le(Buf + 2, Got - Plt + 2); // GOT+8
write32le(Buf + 8, Got - Plt + 4); // GOT+16
}
@ -1255,7 +1255,7 @@ uint32_t AArch64TargetInfo::getDynRel(uint32_t Type) const {
}
void AArch64TargetInfo::writeGotPlt(uint8_t *Buf, const SymbolBody &) const {
write64le(Buf, Out<ELF64LE>::Plt->Addr);
write64le(Buf, In<ELF64LE>::Plt->getVA());
}
static uint64_t getAArch64Page(uint64_t Expr) {
@ -1276,7 +1276,7 @@ void AArch64TargetInfo::writePltHeader(uint8_t *Buf) const {
memcpy(Buf, PltData, sizeof(PltData));
uint64_t Got = In<ELF64LE>::GotPlt->getVA();
uint64_t Plt = Out<ELF64LE>::Plt->Addr;
uint64_t Plt = In<ELF64LE>::Plt->getVA();
relocateOne(Buf + 4, R_AARCH64_ADR_PREL_PG_HI21,
getAArch64Page(Got + 16) - getAArch64Page(Plt + 4));
relocateOne(Buf + 8, R_AARCH64_LDST64_ABS_LO12_NC, Got + 16);
@ -1617,7 +1617,7 @@ uint32_t ARMTargetInfo::getDynRel(uint32_t Type) const {
}
void ARMTargetInfo::writeGotPlt(uint8_t *Buf, const SymbolBody &) const {
write32le(Buf, Out<ELF32LE>::Plt->Addr);
write32le(Buf, In<ELF32LE>::Plt->getVA());
}
void ARMTargetInfo::writePltHeader(uint8_t *Buf) const {
@ -1630,7 +1630,7 @@ void ARMTargetInfo::writePltHeader(uint8_t *Buf) const {
};
memcpy(Buf, PltData, sizeof(PltData));
uint64_t GotPlt = In<ELF32LE>::GotPlt->getVA();
uint64_t L1 = Out<ELF32LE>::Plt->Addr + 8;
uint64_t L1 = In<ELF32LE>::Plt->getVA() + 8;
write32le(Buf + 16, GotPlt - L1 - 8);
}
@ -1997,7 +1997,7 @@ bool MipsTargetInfo<ELFT>::isTlsGlobalDynamicRel(uint32_t Type) const {
template <class ELFT>
void MipsTargetInfo<ELFT>::writeGotPlt(uint8_t *Buf, const SymbolBody &) const {
write32<ELFT::TargetEndianness>(Buf, Out<ELFT>::Plt->Addr);
write32<ELFT::TargetEndianness>(Buf, In<ELFT>::Plt->getVA());
}
template <endianness E, uint8_t BSIZE, uint8_t SHIFT>

View File

@ -212,7 +212,7 @@ template <class ELFT> void Writer<ELFT>::createSyntheticSections() {
In<ELFT>::DynStrTab = make<StringTableSection<ELFT>>(".dynstr", true);
In<ELFT>::Dynamic = make<DynamicSection<ELFT>>();
Out<ELFT>::EhFrame = make<EhOutputSection<ELFT>>();
Out<ELFT>::Plt = make<PltSection<ELFT>>();
In<ELFT>::Plt = make<PltSection<ELFT>>();
In<ELFT>::RelaDyn = make<RelocationSection<ELFT>>(
Config->Rela ? ".rela.dyn" : ".rel.dyn", Config->ZCombreloc);
In<ELFT>::ShStrTab = make<StringTableSection<ELFT>>(".shstrtab", false);
@ -955,7 +955,7 @@ template <class ELFT> void Writer<ELFT>::finalizeSections() {
{In<ELFT>::DynSymTab, In<ELFT>::GnuHashTab, In<ELFT>::HashTab,
In<ELFT>::SymTab, In<ELFT>::ShStrTab, In<ELFT>::StrTab,
In<ELFT>::DynStrTab, In<ELFT>::Got, In<ELFT>::MipsGot, In<ELFT>::GotPlt,
In<ELFT>::RelaDyn, In<ELFT>::RelaPlt, In<ELFT>::Dynamic});
In<ELFT>::RelaDyn, In<ELFT>::RelaPlt, In<ELFT>::Plt, In<ELFT>::Dynamic});
}
template <class ELFT> bool Writer<ELFT>::needsGot() {
@ -1022,8 +1022,8 @@ template <class ELFT> void Writer<ELFT>::addPredefinedSections() {
if (!In<ELFT>::GotPlt->empty())
addInputSec(In<ELFT>::GotPlt);
if (!Out<ELFT>::Plt->empty())
Add(Out<ELFT>::Plt);
if (!In<ELFT>::Plt->empty())
addInputSec(In<ELFT>::Plt);
if (!Out<ELFT>::EhFrame->empty())
Add(Out<ELFT>::EhFrameHdr);
if (Out<ELFT>::Bss->Size > 0)