diff options
author | Sean Fertile <sfertile@ca.ibm.com> | 2018-05-06 19:13:29 +0000 |
---|---|---|
committer | Sean Fertile <sfertile@ca.ibm.com> | 2018-05-06 19:13:29 +0000 |
commit | 204d10b83b912a76d178d9197d26ae5f99cb9a13 (patch) | |
tree | f8a3214c8690d8d0eaa3a5f53eac2ddb3f7c156e /lld/ELF/InputSection.cpp | |
parent | a3a4c8ff0d7f430cbac5cb499fcf56a38a321a80 (diff) |
[PPC64] Emit plt call stubs to the text section rather then the plt section.
On PowerPC calls to functions through the plt must be done through a call stub
that is responsible for:
1) Saving the toc pointer to the stack.
2) Loading the target functions address from the plt into both r12 and the
count register.
3) Indirectly branching to the target function.
Previously we have been emitting these call stubs to the .plt section, however
the .plt section should be reserved for the lazy symbol resolution stubs. This
patch moves the call stubs to the text section by moving the implementation from
writePlt to the thunk framework.
Differential Revision: https://reviews.llvm.org/D46204
Diffstat (limited to 'lld/ELF/InputSection.cpp')
-rw-r--r-- | lld/ELF/InputSection.cpp | 12 |
1 files changed, 7 insertions, 5 deletions
diff --git a/lld/ELF/InputSection.cpp b/lld/ELF/InputSection.cpp index 48a385b6992..3ed909618f2 100644 --- a/lld/ELF/InputSection.cpp +++ b/lld/ELF/InputSection.cpp @@ -740,13 +740,15 @@ void InputSectionBase::relocateAlloc(uint8_t *Buf, uint8_t *BufEnd) { case R_RELAX_TLS_GD_TO_IE_END: Target->relaxTlsGdToIe(BufLoc, Type, TargetVA); break; - case R_PPC_CALL_PLT: + case R_PPC_CALL: // Patch a nop (0x60000000) to a ld. - if (BufLoc + 8 > BufEnd || read32(BufLoc + 4) != 0x60000000) { - error(getErrorLocation(BufLoc) + "call lacks nop, can't restore toc"); - break; + if (Rel.Sym->NeedsTocRestore) { + if (BufLoc + 8 > BufEnd || read32(BufLoc + 4) != 0x60000000) { + error(getErrorLocation(BufLoc) + "call lacks nop, can't restore toc"); + break; + } + write32(BufLoc + 4, 0xe8410018); // ld %r2, 24(%r1) } - write32(BufLoc + 4, 0xe8410018); // ld %r2, 24(%r1) Target->relocateOne(BufLoc, Type, TargetVA); break; default: |