Index: head/contrib/llvm-project/lld/ELF/Arch/PPC.cpp =================================================================== --- head/contrib/llvm-project/lld/ELF/Arch/PPC.cpp +++ head/contrib/llvm-project/lld/ELF/Arch/PPC.cpp @@ -71,12 +71,11 @@ // non-GOT-non-PLT relocations referencing external functions for -fpie/-fPIE. uint32_t glink = in.plt->getVA(); // VA of .glink if (!config->isPic) { - for (const Symbol *sym : in.plt->entries) - if (sym->needsPltAddr) { - writePPC32PltCallStub(buf, sym->getGotPltVA(), nullptr, 0); - buf += 16; - glink += 16; - } + for (const Symbol *sym : cast(in.plt)->canonical_plts) { + writePPC32PltCallStub(buf, sym->getGotPltVA(), nullptr, 0); + buf += 16; + glink += 16; + } } // On PPC Secure PLT ABI, bl foo@plt jumps to a call stub, which loads an Index: head/contrib/llvm-project/lld/ELF/Relocations.cpp =================================================================== --- head/contrib/llvm-project/lld/ELF/Relocations.cpp +++ head/contrib/llvm-project/lld/ELF/Relocations.cpp @@ -1206,6 +1206,7 @@ // PPC32 canonical PLT entries are at the beginning of .glink cast(sym).value = in.plt->headerSize; in.plt->headerSize += 16; + cast(in.plt)->canonical_plts.push_back(&sym); } } sym.needsPltAddr = true; Index: head/contrib/llvm-project/lld/ELF/SyntheticSections.h =================================================================== --- head/contrib/llvm-project/lld/ELF/SyntheticSections.h +++ head/contrib/llvm-project/lld/ELF/SyntheticSections.h @@ -684,7 +684,6 @@ size_t getNumEntries() const { return entries.size(); } size_t headerSize; - size_t footerSize = 0; std::vector entries; }; @@ -703,6 +702,16 @@ bool isNeeded() const override { return !entries.empty(); } void addSymbols(); void addEntry(Symbol &sym); +}; + +class PPC32GlinkSection : public PltSection { +public: + PPC32GlinkSection(); + void writeTo(uint8_t *buf) override; + size_t getSize() const override; + + std::vector canonical_plts; + static constexpr size_t footerSize = 64; }; // This is x86-only. Index: head/contrib/llvm-project/lld/ELF/SyntheticSections.cpp =================================================================== --- head/contrib/llvm-project/lld/ELF/SyntheticSections.cpp +++ head/contrib/llvm-project/lld/ELF/SyntheticSections.cpp @@ -2446,12 +2446,9 @@ : SyntheticSection(SHF_ALLOC | SHF_EXECINSTR, SHT_PROGBITS, 16, ".plt"), headerSize(target->pltHeaderSize) { // On PowerPC, this section contains lazy symbol resolvers. - if (config->emachine == EM_PPC || config->emachine == EM_PPC64) { + if (config->emachine == EM_PPC64) { name = ".glink"; alignment = 4; - // PLTresolve is at the end. - if (config->emachine == EM_PPC) - footerSize = 64; } // On x86 when IBT is enabled, this section contains the second PLT (lazy @@ -2467,11 +2464,6 @@ } void PltSection::writeTo(uint8_t *buf) { - if (config->emachine == EM_PPC) { - writePPC32GlinkSection(buf, entries.size()); - return; - } - // At beginning of PLT, we have code to call the dynamic // linker to resolve dynsyms at runtime. Write such code. target->writePltHeader(buf); @@ -2489,7 +2481,7 @@ } size_t PltSection::getSize() const { - return headerSize + entries.size() * target->pltEntrySize + footerSize; + return headerSize + entries.size() * target->pltEntrySize; } bool PltSection::isNeeded() const { @@ -2541,6 +2533,19 @@ target->addPltSymbols(*this, off); off += target->pltEntrySize; } +} + +PPC32GlinkSection::PPC32GlinkSection() { + name = ".glink"; + alignment = 4; +} + +void PPC32GlinkSection::writeTo(uint8_t *buf) { + writePPC32GlinkSection(buf, entries.size()); +} + +size_t PPC32GlinkSection::getSize() const { + return headerSize + entries.size() * target->pltEntrySize + footerSize; } // This is an x86-only extra PLT section and used only when a security Index: head/contrib/llvm-project/lld/ELF/Writer.cpp =================================================================== --- head/contrib/llvm-project/lld/ELF/Writer.cpp +++ head/contrib/llvm-project/lld/ELF/Writer.cpp @@ -521,7 +521,8 @@ add(in.ibtPlt); } - in.plt = make(); + in.plt = config->emachine == EM_PPC ? make() + : make(); add(in.plt); in.iplt = make(); add(in.iplt);