Index: lld/trunk/ELF/OutputSections.h =================================================================== --- lld/trunk/ELF/OutputSections.h +++ lld/trunk/ELF/OutputSections.h @@ -45,7 +45,6 @@ EHFrame, EHFrameHdr, Merge, - Plt, Regular, VersDef, VersNeed, @@ -130,24 +129,6 @@ 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 @@ 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::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; Index: lld/trunk/ELF/OutputSections.cpp =================================================================== --- lld/trunk/ELF/OutputSections.cpp +++ lld/trunk/ELF/OutputSections.cpp @@ -108,38 +108,6 @@ } } -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 PltSection; -template class PltSection; -template class PltSection; -template class PltSection; - template class OutputSection; template class OutputSection; template class OutputSection; Index: lld/trunk/ELF/Relocations.cpp =================================================================== --- lld/trunk/ELF/Relocations.cpp +++ lld/trunk/ELF/Relocations.cpp @@ -743,7 +743,7 @@ if (needsPlt(Expr)) { if (Body.isInPlt()) continue; - Out::Plt->addEntry(Body); + In::Plt->addEntry(Body); uint32_t Rel; if (Body.isGnuIFunc() && !Preemptible) Index: lld/trunk/ELF/Symbols.cpp =================================================================== --- lld/trunk/ELF/Symbols.cpp +++ lld/trunk/ELF/Symbols.cpp @@ -167,7 +167,7 @@ } template typename ELFT::uint SymbolBody::getPltVA() const { - return Out::Plt->Addr + Target->PltHeaderSize + + return In::Plt->getVA() + Target->PltHeaderSize + PltIndex * Target->PltEntrySize; } Index: lld/trunk/ELF/SyntheticSections.h =================================================================== --- lld/trunk/ELF/SyntheticSections.h +++ lld/trunk/ELF/SyntheticSections.h @@ -490,6 +490,18 @@ 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 @@ 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 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; Index: lld/trunk/ELF/SyntheticSections.cpp =================================================================== --- lld/trunk/ELF/SyntheticSections.cpp +++ lld/trunk/ELF/SyntheticSections.cpp @@ -1329,6 +1329,37 @@ } } +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::PltSection; +template class elf::PltSection; +template class elf::PltSection; +template class elf::PltSection; Index: lld/trunk/ELF/Target.cpp =================================================================== --- lld/trunk/ELF/Target.cpp +++ lld/trunk/ELF/Target.cpp @@ -615,7 +615,7 @@ }; 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 @@ } 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 @@ 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 @@ } 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 @@ }; 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 @@ template void MipsTargetInfo::writeGotPlt(uint8_t *Buf, const SymbolBody &) const { - write32(Buf, Out::Plt->Addr); + write32(Buf, In::Plt->getVA()); } template Index: lld/trunk/ELF/Writer.cpp =================================================================== --- lld/trunk/ELF/Writer.cpp +++ lld/trunk/ELF/Writer.cpp @@ -212,7 +212,7 @@ 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 @@ {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 @@ 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)