[ELF] Convert PltSection to input section
Differential revision: https://reviews.llvm.org/D26842 llvm-svn: 287346
This commit is contained in:
parent
df613198c0
commit
ff23d3e741
|
@ -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>;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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>;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Reference in New Issue