diff --git a/contrib/llvm-project/lld/ELF/Arch/PPC.cpp b/contrib/llvm-project/lld/ELF/Arch/PPC.cpp index b3cc78710e9a..20f5d41acae4 100644 --- a/contrib/llvm-project/lld/ELF/Arch/PPC.cpp +++ b/contrib/llvm-project/lld/ELF/Arch/PPC.cpp @@ -71,12 +71,11 @@ void writePPC32GlinkSection(uint8_t *buf, size_t numEntries) { // 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 diff --git a/contrib/llvm-project/lld/ELF/Relocations.cpp b/contrib/llvm-project/lld/ELF/Relocations.cpp index 93ec06610716..5609fb92fd27 100644 --- a/contrib/llvm-project/lld/ELF/Relocations.cpp +++ b/contrib/llvm-project/lld/ELF/Relocations.cpp @@ -1206,6 +1206,7 @@ static void processRelocAux(InputSectionBase &sec, RelExpr expr, RelType type, // 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; diff --git a/contrib/llvm-project/lld/ELF/SyntheticSections.cpp b/contrib/llvm-project/lld/ELF/SyntheticSections.cpp index ea6eab4b47ad..2ae6277a36a2 100644 --- a/contrib/llvm-project/lld/ELF/SyntheticSections.cpp +++ b/contrib/llvm-project/lld/ELF/SyntheticSections.cpp @@ -2446,12 +2446,9 @@ PltSection::PltSection() : 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 @@ PltSection::PltSection() } 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 @@ void PltSection::addEntry(Symbol &sym) { } size_t PltSection::getSize() const { - return headerSize + entries.size() * target->pltEntrySize + footerSize; + return headerSize + entries.size() * target->pltEntrySize; } bool PltSection::isNeeded() const { @@ -2543,6 +2535,19 @@ void IpltSection::addSymbols() { } } +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 // enhancement feature called CET is enabled. In this comment, I'll explain what // the feature is and why we have two PLT sections if CET is enabled. diff --git a/contrib/llvm-project/lld/ELF/SyntheticSections.h b/contrib/llvm-project/lld/ELF/SyntheticSections.h index 5f59178fb541..190a4fd3ac9e 100644 --- a/contrib/llvm-project/lld/ELF/SyntheticSections.h +++ b/contrib/llvm-project/lld/ELF/SyntheticSections.h @@ -684,7 +684,6 @@ class PltSection : public SyntheticSection { size_t getNumEntries() const { return entries.size(); } size_t headerSize; - size_t footerSize = 0; std::vector entries; }; @@ -705,6 +704,16 @@ class IpltSection final : public SyntheticSection { 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. class IBTPltSection : public SyntheticSection { public: diff --git a/contrib/llvm-project/lld/ELF/Writer.cpp b/contrib/llvm-project/lld/ELF/Writer.cpp index ac332de2a057..43ec63945d62 100644 --- a/contrib/llvm-project/lld/ELF/Writer.cpp +++ b/contrib/llvm-project/lld/ELF/Writer.cpp @@ -521,7 +521,8 @@ template void createSyntheticSections() { add(in.ibtPlt); } - in.plt = make(); + in.plt = config->emachine == EM_PPC ? make() + : make(); add(in.plt); in.iplt = make(); add(in.iplt);