From ff23d3e741ee9d7f7f1bd4a5cb0ff43b8b76389b Mon Sep 17 00:00:00 2001 From: Eugene Leviant Date: Fri, 18 Nov 2016 14:35:03 +0000 Subject: [PATCH] [ELF] Convert PltSection to input section Differential revision: https://reviews.llvm.org/D26842 llvm-svn: 287346 --- lld/ELF/OutputSections.cpp | 37 ------------------------------------- lld/ELF/OutputSections.h | 21 --------------------- lld/ELF/Relocations.cpp | 2 +- lld/ELF/Symbols.cpp | 2 +- lld/ELF/SyntheticSections.cpp | 36 ++++++++++++++++++++++++++++++++++++ lld/ELF/SyntheticSections.h | 14 ++++++++++++++ lld/ELF/Target.cpp | 12 ++++++------ lld/ELF/Writer.cpp | 8 ++++---- 8 files changed, 62 insertions(+), 70 deletions(-) diff --git a/lld/ELF/OutputSections.cpp b/lld/ELF/OutputSections.cpp index 2119882..cdbe628 100644 --- a/lld/ELF/OutputSections.cpp +++ b/lld/ELF/OutputSections.cpp @@ -108,38 +108,6 @@ template void GdbIndexSection::writeTo(uint8_t *Buf) { } } -template -PltSection::PltSection() - : OutputSectionBase(".plt", SHT_PROGBITS, SHF_ALLOC | SHF_EXECINSTR) { - this->Addralign = 16; -} - -template void PltSection::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(); - uint64_t Plt = this->Addr + Off; - Target->writePlt(Buf + Off, Got, Plt, B->PltIndex, RelOff); - Off += Target->PltEntrySize; - } -} - -template void PltSection::addEntry(SymbolBody &Sym) { - Sym.PltIndex = Entries.size(); - unsigned RelOff = In::RelaPlt->getRelocOffset(); - Entries.push_back(std::make_pair(&Sym, RelOff)); -} - -template void PltSection::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; template class EhFrameHeader; template class EhFrameHeader; -template class PltSection; -template class PltSection; -template class PltSection; -template class PltSection; - template class OutputSection; template class OutputSection; template class OutputSection; diff --git a/lld/ELF/OutputSections.h b/lld/ELF/OutputSections.h index df4707a..0c1c027 100644 --- a/lld/ELF/OutputSections.h +++ b/lld/ELF/OutputSections.h @@ -45,7 +45,6 @@ public: EHFrame, EHFrameHdr, Merge, - Plt, Regular, VersDef, VersNeed, @@ -130,24 +129,6 @@ private: uint32_t CuTypesOffset; }; -template 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> Entries; -}; - // For more information about .gnu.version and .gnu.version_r see: // https://www.akkadia.org/drepper/symbol-versioning @@ -362,7 +343,6 @@ template struct Out { static OutputSection *MipsRldMap; static OutputSectionBase *Opd; static uint8_t *OpdBuf; - static PltSection *Plt; static VersionDefinitionSection *VerDef; static VersionTableSection *VerSym; static VersionNeedSection *VerNeed; @@ -416,7 +396,6 @@ template OutputSection *Out::Bss; template OutputSection *Out::MipsRldMap; template OutputSectionBase *Out::Opd; template uint8_t *Out::OpdBuf; -template PltSection *Out::Plt; template VersionDefinitionSection *Out::VerDef; template VersionTableSection *Out::VerSym; template VersionNeedSection *Out::VerNeed; diff --git a/lld/ELF/Relocations.cpp b/lld/ELF/Relocations.cpp index c402bce..8bcf4d2 100644 --- a/lld/ELF/Relocations.cpp +++ b/lld/ELF/Relocations.cpp @@ -743,7 +743,7 @@ static void scanRelocs(InputSectionBase &C, ArrayRef Rels) { if (needsPlt(Expr)) { if (Body.isInPlt()) continue; - Out::Plt->addEntry(Body); + In::Plt->addEntry(Body); uint32_t Rel; if (Body.isGnuIFunc() && !Preemptible) diff --git a/lld/ELF/Symbols.cpp b/lld/ELF/Symbols.cpp index 89053d1..255bd32 100644 --- a/lld/ELF/Symbols.cpp +++ b/lld/ELF/Symbols.cpp @@ -167,7 +167,7 @@ template typename ELFT::uint SymbolBody::getGotPltOffset() const { } template typename ELFT::uint SymbolBody::getPltVA() const { - return Out::Plt->Addr + Target->PltHeaderSize + + return In::Plt->getVA() + Target->PltHeaderSize + PltIndex * Target->PltEntrySize; } diff --git a/lld/ELF/SyntheticSections.cpp b/lld/ELF/SyntheticSections.cpp index c6c4b75..8f66ade0 100644 --- a/lld/ELF/SyntheticSections.cpp +++ b/lld/ELF/SyntheticSections.cpp @@ -1329,6 +1329,37 @@ template void HashTableSection::writeTo(uint8_t *Buf) { } } +template +PltSection::PltSection() + : SyntheticSection(SHF_ALLOC | SHF_EXECINSTR, SHT_PROGBITS, 16, + ".plt") {} + +template void PltSection::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(); + uint64_t Plt = this->getVA() + Off; + Target->writePlt(Buf + Off, Got, Plt, B->PltIndex, RelOff); + Off += Target->PltEntrySize; + } +} + +template void PltSection::addEntry(SymbolBody &Sym) { + Sym.PltIndex = Entries.size(); + unsigned RelOff = In::RelaPlt->getRelocOffset(); + Entries.push_back(std::make_pair(&Sym, RelOff)); +} + +template size_t PltSection::getSize() const { + return Target->PltHeaderSize + Entries.size() * Target->PltEntrySize; +} + template InputSection *elf::createCommonSection(); template InputSection *elf::createCommonSection(); template InputSection *elf::createCommonSection(); @@ -1433,3 +1464,8 @@ template class elf::HashTableSection; template class elf::HashTableSection; template class elf::HashTableSection; template class elf::HashTableSection; + +template class elf::PltSection; +template class elf::PltSection; +template class elf::PltSection; +template class elf::PltSection; diff --git a/lld/ELF/SyntheticSections.h b/lld/ELF/SyntheticSections.h index e3e927a9..e441f99 100644 --- a/lld/ELF/SyntheticSections.h +++ b/lld/ELF/SyntheticSections.h @@ -490,6 +490,18 @@ private: size_t Size = 0; }; +template class PltSection final : public SyntheticSection { +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> Entries; +}; + template InputSection *createCommonSection(); template InputSection *createInterpSection(); template MergeInputSection *createCommentSection(); @@ -510,6 +522,7 @@ template struct In { static MipsAbiFlagsSection *MipsAbiFlags; static MipsOptionsSection *MipsOptions; static MipsReginfoSection *MipsReginfo; + static PltSection *Plt; static RelocationSection *RelaDyn; static RelocationSection *RelaPlt; static StringTableSection *ShStrTab; @@ -531,6 +544,7 @@ template InputSection *In::Interp; template MipsAbiFlagsSection *In::MipsAbiFlags; template MipsOptionsSection *In::MipsOptions; template MipsReginfoSection *In::MipsReginfo; +template PltSection *In::Plt; template RelocationSection *In::RelaDyn; template RelocationSection *In::RelaPlt; template StringTableSection *In::ShStrTab; diff --git a/lld/ELF/Target.cpp b/lld/ELF/Target.cpp index 3ad2316..bcada08 100644 --- a/lld/ELF/Target.cpp +++ b/lld/ELF/Target.cpp @@ -615,7 +615,7 @@ void X86_64TargetInfo::writePltHeader(uint8_t *Buf) const { }; memcpy(Buf, PltData, sizeof(PltData)); uint64_t Got = In::GotPlt->getVA(); - uint64_t Plt = Out::Plt->Addr; + uint64_t Plt = In::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::Plt->Addr); + write64le(Buf, In::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::GotPlt->getVA(); - uint64_t Plt = Out::Plt->Addr; + uint64_t Plt = In::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::Plt->Addr); + write32le(Buf, In::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::GotPlt->getVA(); - uint64_t L1 = Out::Plt->Addr + 8; + uint64_t L1 = In::Plt->getVA() + 8; write32le(Buf + 16, GotPlt - L1 - 8); } @@ -1997,7 +1997,7 @@ bool MipsTargetInfo::isTlsGlobalDynamicRel(uint32_t Type) const { template void MipsTargetInfo::writeGotPlt(uint8_t *Buf, const SymbolBody &) const { - write32(Buf, Out::Plt->Addr); + write32(Buf, In::Plt->getVA()); } template diff --git a/lld/ELF/Writer.cpp b/lld/ELF/Writer.cpp index e740183..35a792a 100644 --- a/lld/ELF/Writer.cpp +++ b/lld/ELF/Writer.cpp @@ -212,7 +212,7 @@ template void Writer::createSyntheticSections() { In::DynStrTab = make>(".dynstr", true); In::Dynamic = make>(); Out::EhFrame = make>(); - Out::Plt = make>(); + In::Plt = make>(); In::RelaDyn = make>( Config->Rela ? ".rela.dyn" : ".rel.dyn", Config->ZCombreloc); In::ShStrTab = make>(".shstrtab", false); @@ -955,7 +955,7 @@ template void Writer::finalizeSections() { {In::DynSymTab, In::GnuHashTab, In::HashTab, In::SymTab, In::ShStrTab, In::StrTab, In::DynStrTab, In::Got, In::MipsGot, In::GotPlt, - In::RelaDyn, In::RelaPlt, In::Dynamic}); + In::RelaDyn, In::RelaPlt, In::Plt, In::Dynamic}); } template bool Writer::needsGot() { @@ -1022,8 +1022,8 @@ template void Writer::addPredefinedSections() { if (!In::GotPlt->empty()) addInputSec(In::GotPlt); - if (!Out::Plt->empty()) - Add(Out::Plt); + if (!In::Plt->empty()) + addInputSec(In::Plt); if (!Out::EhFrame->empty()) Add(Out::EhFrameHdr); if (Out::Bss->Size > 0) -- 2.7.4