diff --git a/lld/ELF/Arch/PPC.cpp b/lld/ELF/Arch/PPC.cpp --- a/lld/ELF/Arch/PPC.cpp +++ b/lld/ELF/Arch/PPC.cpp @@ -76,12 +76,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 diff --git a/lld/ELF/Relocations.cpp b/lld/ELF/Relocations.cpp --- a/lld/ELF/Relocations.cpp +++ b/lld/ELF/Relocations.cpp @@ -1226,6 +1226,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; diff --git a/lld/ELF/SyntheticSections.h b/lld/ELF/SyntheticSections.h --- a/lld/ELF/SyntheticSections.h +++ b/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; }; @@ -705,6 +704,16 @@ 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/lld/ELF/SyntheticSections.cpp b/lld/ELF/SyntheticSections.cpp --- a/lld/ELF/SyntheticSections.cpp +++ b/lld/ELF/SyntheticSections.cpp @@ -2447,12 +2447,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 @@ -2468,11 +2465,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); @@ -2490,7 +2482,7 @@ } size_t PltSection::getSize() const { - return headerSize + entries.size() * target->pltEntrySize + footerSize; + return headerSize + entries.size() * target->pltEntrySize; } bool PltSection::isNeeded() const { @@ -2544,6 +2536,19 @@ } } +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/lld/ELF/Writer.cpp b/lld/ELF/Writer.cpp --- a/lld/ELF/Writer.cpp +++ b/lld/ELF/Writer.cpp @@ -525,7 +525,8 @@ add(in.ibtPlt); } - in.plt = make(); + in.plt = config->emachine == EM_PPC ? make() + : make(); add(in.plt); in.iplt = make(); add(in.iplt); diff --git a/lld/test/ELF/Inputs/canonical-plt-pcrel.s b/lld/test/ELF/Inputs/canonical-plt-pcrel.s --- a/lld/test/ELF/Inputs/canonical-plt-pcrel.s +++ b/lld/test/ELF/Inputs/canonical-plt-pcrel.s @@ -1,5 +1,7 @@ -.globl func, ifunc +.globl func, func2, ifunc .type func, @function +.type func2, @function .type ifunc, @gnu_indirect_function func: +func2: ifunc: diff --git a/lld/test/ELF/ppc32-canonical-plt.s b/lld/test/ELF/ppc32-canonical-plt.s --- a/lld/test/ELF/ppc32-canonical-plt.s +++ b/lld/test/ELF/ppc32-canonical-plt.s @@ -14,49 +14,59 @@ # REL: Relocations [ # REL-NEXT: .rela.plt { -# REL-NEXT: R_PPC_JMP_SLOT func 0x0 -# REL-NEXT: R_PPC_JMP_SLOT ifunc 0x0 +# REL-NEXT: 0x10030318 R_PPC_JMP_SLOT func 0x0 +# REL-NEXT: 0x1003031C R_PPC_JMP_SLOT func2 0x0 +# REL-NEXT: 0x10030320 R_PPC_JMP_SLOT ifunc 0x0 # REL-NEXT: } # REL-NEXT: ] -# SYM: .glink PROGBITS 100101dc +# SYM: .glink PROGBITS 1001022c ## st_value points to the canonical PLT entry in .glink # SYM: Symbol table '.dynsym' -# SYM: 100101dc 0 FUNC GLOBAL DEFAULT UND func -# SYM: 100101ec 0 FUNC GLOBAL DEFAULT UND ifunc +# SYM: 1001023c 0 FUNC GLOBAL DEFAULT UND func +# SYM: 1001022c 0 FUNC GLOBAL DEFAULT UND func2 +# SYM: 1001024c 0 FUNC GLOBAL DEFAULT UND ifunc # SYM: Symbol table '.symtab' -# SYM: 100101dc 0 FUNC GLOBAL DEFAULT UND func -# SYM: 100101ec 0 FUNC GLOBAL DEFAULT UND ifunc +# SYM: 1001023c 0 FUNC GLOBAL DEFAULT UND func +# SYM: 1001022c 0 FUNC GLOBAL DEFAULT UND func2 +# SYM: 1001024c 0 FUNC GLOBAL DEFAULT UND ifunc -# HEX: 0x100302b4 100101fc 10010200 +# HEX: 0x10030318 1001025c 10010260 10010264 -## Canonical PLT entry of func. -## 0x100101dc + 4*2 + 64 = 0x10010224 -## 0x1001021c = 65536*4099+692 -# CHECK: 100101dc .glink: +## Canonical PLT entry of func2. +## 0x1003031C = 65536*4099+796 +# CHECK: 1001022c .glink: # CHECK-NEXT: lis 11, 4099 -# CHECK-NEXT: lwz 11, 692(11) +# CHECK-NEXT: lwz 11, 796(11) +# CHECK-NEXT: mtctr 11 +# CHECK-NEXT: bctr + +## Canonical PLT entry of func. +## 0x10030318 = 65536*4099+792 +# CHECK-NEXT: 1001023c: lis 11, 4099 +# CHECK-NEXT: lwz 11, 792(11) # CHECK-NEXT: mtctr 11 # CHECK-NEXT: bctr ## Canonical PLT entry of ifunc. -## 0x10010220 = 65536*4099+696 -# CHECK-NEXT: 100101ec: lis 11, 4099 -# CHECK-NEXT: lwz 11, 696(11) +## 0x10030320 = 65536*4099+800 +# CHECK-NEXT: 1001024c: lis 11, 4099 +# CHECK-NEXT: lwz 11, 800(11) # CHECK-NEXT: mtctr 11 # CHECK-NEXT: bctr -## The 2 b instructions are referenced by .plt entries. -# CHECK-NEXT: 100101fc: b .+8 +## The 3 b instructions are referenced by .plt entries. +# CHECK-NEXT: 1001025c: b .+12 +# CHECK-NEXT: b .+8 # CHECK-NEXT: b .+4 ## PLTresolve of 64 bytes is at the end. -## Operands of addis & addi: -0x100101fc = 65536*-4097-508 +## Operands of addis & addi: -0x1001025c = 65536*-4097-604 # CHECK-NEXT: lis 12, 0 # CHECK-NEXT: addis 11, 11, -4097 # CHECK-NEXT: lwz 0, 4(12) -# CHECK-NEXT: addi 11, 11, -508 +# CHECK-NEXT: addi 11, 11, -604 # CHECK-NEXT: mtctr 0 # CHECK-NEXT: add 0, 11, 11 # CHECK-NEXT: lwz 12, 8(12) @@ -66,6 +76,9 @@ .globl _start _start: + b func + lis 3, func2@ha + la 3, func2@l(3) lis 3, func@ha la 3, func@l(3) lis 4, ifunc@ha