diff options
Diffstat (limited to 'lld/ELF/Arch/PPC.cpp')
-rw-r--r-- | lld/ELF/Arch/PPC.cpp | 20 |
1 files changed, 16 insertions, 4 deletions
diff --git a/lld/ELF/Arch/PPC.cpp b/lld/ELF/Arch/PPC.cpp index c4eecb9a29c2..3c0b0c290b58 100644 --- a/lld/ELF/Arch/PPC.cpp +++ b/lld/ELF/Arch/PPC.cpp @@ -10,6 +10,7 @@ #include "Symbols.h" #include "SyntheticSections.h" #include "Target.h" +#include "Thunks.h" #include "lld/Common/ErrorHandler.h" #include "llvm/Support/Endian.h" @@ -31,13 +32,16 @@ public: void writePltHeader(uint8_t *buf) const override { llvm_unreachable("should call writePPC32GlinkSection() instead"); } - void writePlt(uint8_t *buf, uint64_t gotPltEntryAddr, uint64_t pltEntryAddr, - int32_t index, unsigned relOff) const override { + void writePlt(uint8_t *buf, const Symbol &sym, + uint64_t pltEntryAddr) const override { llvm_unreachable("should call writePPC32GlinkSection() instead"); } + void writeIplt(uint8_t *buf, const Symbol &sym, + uint64_t pltEntryAddr) const override; void writeGotPlt(uint8_t *buf, const Symbol &s) const override; bool needsThunk(RelExpr expr, RelType relocType, const InputFile *file, - uint64_t branchAddr, const Symbol &s) const override; + uint64_t branchAddr, const Symbol &s, + int64_t a) const override; uint32_t getThunkSectionSpacing() const override; bool inBranchRange(RelType type, uint64_t src, uint64_t dst) const override; void relocateOne(uint8_t *loc, RelType type, uint64_t val) const override; @@ -143,6 +147,7 @@ PPC::PPC() { gotPltHeaderEntriesNum = 0; pltHeaderSize = 64; // size of PLTresolve in .glink pltEntrySize = 4; + ipltEntrySize = 16; needsThunks = true; @@ -156,6 +161,13 @@ PPC::PPC() { write32(trapInstr.data(), 0x7fe00008); } +void PPC::writeIplt(uint8_t *buf, const Symbol &sym, + uint64_t /*pltEntryAddr*/) const { + // In -pie or -shared mode, assume r30 points to .got2+0x8000, and use a + // .got2.plt_pic32. thunk. + writePPC32PltCallStub(buf, sym.getGotPltVA(), sym.file, 0x8000); +} + void PPC::writeGotHeader(uint8_t *buf) const { // _GLOBAL_OFFSET_TABLE_[0] = _DYNAMIC // glibc stores _dl_runtime_resolve in _GLOBAL_OFFSET_TABLE_[1], @@ -169,7 +181,7 @@ void PPC::writeGotPlt(uint8_t *buf, const Symbol &s) const { } bool PPC::needsThunk(RelExpr expr, RelType type, const InputFile *file, - uint64_t branchAddr, const Symbol &s) const { + uint64_t branchAddr, const Symbol &s, int64_t /*a*/) const { if (type != R_PPC_REL24 && type != R_PPC_PLTREL24) return false; if (s.isInPlt()) |