summaryrefslogtreecommitdiff
path: root/lld/ELF/InputSection.cpp
diff options
context:
space:
mode:
authorSean Fertile <sfertile@ca.ibm.com>2018-05-06 19:13:29 +0000
committerSean Fertile <sfertile@ca.ibm.com>2018-05-06 19:13:29 +0000
commit204d10b83b912a76d178d9197d26ae5f99cb9a13 (patch)
treef8a3214c8690d8d0eaa3a5f53eac2ddb3f7c156e /lld/ELF/InputSection.cpp
parenta3a4c8ff0d7f430cbac5cb499fcf56a38a321a80 (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.cpp12
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: