}
}
-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.
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>;
EHFrame,
EHFrameHdr,
Merge,
- Plt,
Regular,
VersDef,
VersNeed,
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
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;
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;
if (needsPlt(Expr)) {
if (Body.isInPlt())
continue;
- Out<ELFT>::Plt->addEntry(Body);
+ In<ELFT>::Plt->addEntry(Body);
uint32_t Rel;
if (Body.isGnuIFunc() && !Preemptible)
}
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;
}
}
}
+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();
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>;
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();
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;
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;
};
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
}
}
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) {
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);
}
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 {
};
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);
}
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>
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);
{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() {
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)