Index: lld/trunk/ELF/SyntheticSections.h =================================================================== --- lld/trunk/ELF/SyntheticSections.h +++ lld/trunk/ELF/SyntheticSections.h @@ -234,7 +234,7 @@ std::vector Entries; }; -// The IgotPltSection is a Got associated with the IpltSection for GNU Ifunc +// The IgotPltSection is a Got associated with the PltSection for GNU Ifunc // Symbols that will be relocated by Target->IRelativeRel. // On most Targets the IgotPltSection will immediately follow the GotPltSection // on ARM the IgotPltSection will immediately follow the GotSection. @@ -461,25 +461,13 @@ size_t Size = 0; }; -template class PltSection final : public SyntheticSection { +// The PltSection is used for both the Plt and Iplt. The former always has a +// header as its first entry that is used at run-time to resolve lazy binding. +// The latter is used for GNU Ifunc symbols, that will be subject to a +// Target->IRelativeRel. +template class PltSection : public SyntheticSection { public: - PltSection(); - void writeTo(uint8_t *Buf) override; - size_t getSize() const override; - void addEntry(SymbolBody &Sym); - bool empty() const override { return Entries.empty(); } - void addSymbols(); - -private: - std::vector> Entries; -}; - -// The IpltSection is a variant of Plt for recording entries for GNU Ifunc -// symbols that will be subject to a Target->IRelativeRel -// The IpltSection immediately follows the Plt section in the Output Section -template class IpltSection final : public SyntheticSection { -public: - IpltSection(); + PltSection(size_t HeaderSize); void writeTo(uint8_t *Buf) override; size_t getSize() const override; void addEntry(SymbolBody &Sym); @@ -487,7 +475,12 @@ void addSymbols(); private: + void writeHeader(uint8_t *Buf){}; + void addHeaderSymbols(){}; + unsigned getPltRelocOff() const; std::vector> Entries; + // Iplt always has HeaderSize of 0, the Plt HeaderSize is always non-zero + size_t HeaderSize; }; template @@ -777,7 +770,7 @@ static InputSection *Interp; static MipsRldMapSection *MipsRldMap; static PltSection *Plt; - static IpltSection *Iplt; + static PltSection *Iplt; static RelocationSection *RelaDyn; static RelocationSection *RelaPlt; static RelocationSection *RelaIplt; @@ -806,7 +799,7 @@ template InputSection *In::Interp; template MipsRldMapSection *In::MipsRldMap; template PltSection *In::Plt; -template IpltSection *In::Iplt; +template PltSection *In::Iplt; template RelocationSection *In::RelaDyn; template RelocationSection *In::RelaPlt; template RelocationSection *In::RelaIplt; Index: lld/trunk/ELF/SyntheticSections.cpp =================================================================== --- lld/trunk/ELF/SyntheticSections.cpp +++ lld/trunk/ELF/SyntheticSections.cpp @@ -1434,19 +1434,23 @@ } template -PltSection::PltSection() +PltSection::PltSection(size_t S) : SyntheticSection(SHF_ALLOC | SHF_EXECINSTR, SHT_PROGBITS, 16, - ".plt") {} + ".plt"), + HeaderSize(S) {} 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; + // At beginning of PLT but not the IPLT, we have code to call the dynamic + // linker to resolve dynsyms at runtime. Write such code. + if (HeaderSize != 0) + Target->writePltHeader(Buf); + size_t Off = HeaderSize; + // The IPlt is immediately after the Plt, account for this in RelOff + unsigned PltOff = getPltRelocOff(); for (auto &I : Entries) { const SymbolBody *B = I.first; - unsigned RelOff = I.second; + unsigned RelOff = I.second + PltOff; uint64_t Got = B->getGotPltVA(); uint64_t Plt = this->getVA() + Off; Target->writePlt(Buf + Off, Got, Plt, B->PltIndex, RelOff); @@ -1456,61 +1460,34 @@ template void PltSection::addEntry(SymbolBody &Sym) { Sym.PltIndex = Entries.size(); - unsigned RelOff = In::RelaPlt->getRelocOffset(); + RelocationSection *PltRelocSection = In::RelaPlt; + if (HeaderSize == 0) { + PltRelocSection = In::RelaIplt; + Sym.IsInIplt = true; + } + unsigned RelOff = PltRelocSection->getRelocOffset(); Entries.push_back(std::make_pair(&Sym, RelOff)); } template size_t PltSection::getSize() const { - return Target->PltHeaderSize + Entries.size() * Target->PltEntrySize; + return HeaderSize + Entries.size() * Target->PltEntrySize; } // Some architectures such as additional symbols in the PLT section. For // example ARM uses mapping symbols to aid disassembly template void PltSection::addSymbols() { - Target->addPltHeaderSymbols(this); - size_t Off = Target->PltHeaderSize; + // The PLT may have symbols defined for the Header, the IPLT has no header + if (HeaderSize != 0) + Target->addPltHeaderSymbols(this); + size_t Off = HeaderSize; for (size_t I = 0; I < Entries.size(); ++I) { Target->addPltSymbols(this, Off); Off += Target->PltEntrySize; } } -template -IpltSection::IpltSection() - : SyntheticSection(SHF_ALLOC | SHF_EXECINSTR, SHT_PROGBITS, 16, - ".plt") {} - -template void IpltSection::writeTo(uint8_t *Buf) { - // The IRelative relocations do not support lazy binding so no header is - // needed - size_t Off = 0; - for (auto &I : Entries) { - const SymbolBody *B = I.first; - unsigned RelOff = I.second + In::Plt->getSize(); - 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 IpltSection::addEntry(SymbolBody &Sym) { - Sym.PltIndex = Entries.size(); - Sym.IsInIplt = true; - unsigned RelOff = In::RelaIplt->getRelocOffset(); - Entries.push_back(std::make_pair(&Sym, RelOff)); -} - -template size_t IpltSection::getSize() const { - return Entries.size() * Target->PltEntrySize; -} - -template void IpltSection::addSymbols() { - size_t Off = 0; - for (size_t I = 0; I < Entries.size(); ++I) { - Target->addPltSymbols(this, Off); - Off += Target->PltEntrySize; - } +template unsigned PltSection::getPltRelocOff() const { + return (HeaderSize == 0) ? In::Plt->getSize() : 0; } template @@ -2118,11 +2095,6 @@ template class elf::PltSection; template class elf::PltSection; -template class elf::IpltSection; -template class elf::IpltSection; -template class elf::IpltSection; -template class elf::IpltSection; - template class elf::GdbIndexSection; template class elf::GdbIndexSection; template class elf::GdbIndexSection; Index: lld/trunk/ELF/Writer.cpp =================================================================== --- lld/trunk/ELF/Writer.cpp +++ lld/trunk/ELF/Writer.cpp @@ -426,9 +426,9 @@ false /*Sort*/); Add(In::RelaIplt); - In::Plt = make>(); + In::Plt = make>(Target->PltHeaderSize); Add(In::Plt); - In::Iplt = make>(); + In::Iplt = make>(0); Add(In::Iplt); if (Config->EhFrameHdr) {