diff --git a/lld/ELF/Thunks.cpp b/lld/ELF/Thunks.cpp --- a/lld/ELF/Thunks.cpp +++ b/lld/ELF/Thunks.cpp @@ -399,24 +399,6 @@ } }; -// A bl instruction uses a signed 24 bit offset, with an implicit 4 byte -// alignment. This gives a possible 26 bits of 'reach'. If the caller and -// callee do not use toc and the call offset is larger than 26 bits, -// we need to emit a pc-rel based long-branch thunk. The target address of -// the callee is computed with a PC-relative offset. -class PPC64PCRelLongBranchThunk final : public Thunk { -public: - PPC64PCRelLongBranchThunk(Symbol &dest, int64_t addend) - : Thunk(dest, addend) { - alignment = 16; - } - uint32_t size() override { return 32; } - void writeTo(uint8_t *buf) override; - void addSymbols(ThunkSection &isec) override; - bool isCompatibleWith(const InputSection &isec, - const Relocation &rel) const override; -}; - } // end anonymous namespace Defined *Thunk::addSymbol(StringRef name, uint8_t type, uint64_t value, @@ -1061,42 +1043,6 @@ return rel.type == R_PPC64_REL24 || rel.type == R_PPC64_REL14; } -void PPC64PCRelLongBranchThunk::writeTo(uint8_t *buf) { - int64_t offset = destination.getVA() - getThunkTargetSym()->getVA(); - if (!isInt<34>(offset)) - reportRangeError(buf, offset, 34, destination, - "PC-relative long branch stub offset"); - - int nextInstOffset; - if (!config->power10Stubs) { - uint32_t off = destination.getVA(addend) - getThunkTargetSym()->getVA() - 8; - write32(buf + 0, 0x7c0802a6); // mflr r12 - write32(buf + 4, 0x429f0005); // bcl 20,31,.+4 - write32(buf + 8, 0x7d6802a6); // mflr r11 - write32(buf + 12, 0x7d8803a6); // mtlr r12 - write32(buf + 16, 0x3d8b0000 | computeHiBits(off)); // addis r12,r11,off@ha - write32(buf + 20, 0x398c0000 | (off & 0xffff)); // addi r12,r12,off@l - nextInstOffset = 24; - } else { - uint64_t paddi = PADDI_R12_NO_DISP | (((offset >> 16) & 0x3ffff) << 32) | - (offset & 0xffff); - writePrefixedInstruction(buf + 0, paddi); // paddi r12, 0, func@pcrel, 1 - nextInstOffset = 8; - } - write32(buf + nextInstOffset, MTCTR_R12); // mtctr r12 - write32(buf + nextInstOffset + 4, BCTR); // bctr -} - -void PPC64PCRelLongBranchThunk::addSymbols(ThunkSection &isec) { - addSymbol(saver.save("__long_branch_pcrel_" + destination.getName()), - STT_FUNC, 0, isec); -} - -bool PPC64PCRelLongBranchThunk::isCompatibleWith(const InputSection &isec, - const Relocation &rel) const { - return rel.type == R_PPC64_REL24_NOTOC; -} - Thunk::Thunk(Symbol &d, int64_t a) : destination(d), addend(a), offset(0) {} Thunk::~Thunk() = default; @@ -1223,9 +1169,7 @@ return make(s, a); if (type == R_PPC64_REL24_NOTOC) - return (s.stOther >> 5) > 1 - ? (Thunk *)make(s) - : (Thunk *)make(s, a); + return make(s); if (config->picThunk) return make(s, a); diff --git a/lld/test/ELF/ppc64-pcrel-cross-link.s b/lld/test/ELF/ppc64-pcrel-cross-link.s --- a/lld/test/ELF/ppc64-pcrel-cross-link.s +++ b/lld/test/ELF/ppc64-pcrel-cross-link.s @@ -29,7 +29,7 @@ # NOSWAP-NEXT: blr # NOSWAP-LABEL: 10030010 <__gep_setup_callee_toc>: # NOSWAP: bctr -# NOSWAP-LABEL: 10030030 <__long_branch_pcrel_callee_notoc>: +# NOSWAP-LABEL: 10030030 <__gep_setup_callee_notoc>: # NOSWAP: bctr # NOSWAP-LABEL: 10040000 : # NOSWAP: bl 0x10040020 @@ -68,7 +68,7 @@ # SWAP-NEXT: blr # SWAP-LABEL: 10040010 <__gep_setup_callee_toc>: # SWAP: bctr -# SWAP-LABEL: 10040030 <__long_branch_pcrel_callee_notoc>: +# SWAP-LABEL: 10040030 <__gep_setup_callee_notoc>: # SWAP: bctr #--- lds diff --git a/lld/test/ELF/ppc64-pcrel-long-branch-error.s b/lld/test/ELF/ppc64-pcrel-long-branch-error.s --- a/lld/test/ELF/ppc64-pcrel-long-branch-error.s +++ b/lld/test/ELF/ppc64-pcrel-long-branch-error.s @@ -18,7 +18,8 @@ # RUN: ld.lld -shared --script %t/lds %t.o -o %t1 --noinhibit-exec # RUN: rm %t.o %t1 -# CHECK: error: PC-relative long branch stub offset is out of range: 8589934592 is not in [-8589934592, 8589934591]; references high +## Note: GNU ld uses sldi 11, 11, 34 and add 12, 11, 12 to support offsets beyond +-2**33. +# CHECK: error: R12 setup stub offset is out of range: 8589934592 is not in [-8589934592, 8589934591]; references high # CHECK-NEXT: >>> defined in {{.*}}.o //--- asm diff --git a/lld/test/ELF/ppc64-pcrel-long-branch.s b/lld/test/ELF/ppc64-pcrel-long-branch.s --- a/lld/test/ELF/ppc64-pcrel-long-branch.s +++ b/lld/test/ELF/ppc64-pcrel-long-branch.s @@ -27,7 +27,7 @@ # CHECK-NEXT: trap ## Callee address - program counter = 0x2002000 - 0x2010 = 33554416 -# CHECK-LABEL: <__long_branch_pcrel_high>: +# CHECK-LABEL: <__gep_setup_high>: # CHECK-NEXT: 2010: paddi 12, 0, 33554416, 1 # CHECK-NEXT: mtctr 12 # CHECK-NEXT: bctr