summaryrefslogtreecommitdiff
path: root/lld/ELF/InputSection.cpp
diff options
context:
space:
mode:
authorZaara Syeda <syzaara@ca.ibm.com>2018-04-27 15:41:19 +0000
committerZaara Syeda <syzaara@ca.ibm.com>2018-04-27 15:41:19 +0000
commita3e781e4150a4e2e5ed20ab0d40574535c2d76c5 (patch)
tree8853fe4993c3cb81d9f1f8b7ea1929bf5e0202e0 /lld/ELF/InputSection.cpp
parentb7a62396aca1d65e6e4f2e2dcb3861a352f6f3b3 (diff)
[PPC64] Add offset to local entry point when calling functions without plt
PPC64 V2 ABI describes two entry points to a function. The global entry point sets up the TOC base pointer. When calling a local function, the call should branch to the local entry point rather than the global entry point. Section 3.4.1 describes using the 3 most significant bits of the st_other field to find out how many instructions there are between the local and global entry point. This patch adds the correct offset required to branch to the local entry point of a function. Differential Revision: https://reviews.llvm.org/D45729
Diffstat (limited to 'lld/ELF/InputSection.cpp')
-rw-r--r--lld/ELF/InputSection.cpp13
1 files changed, 12 insertions, 1 deletions
diff --git a/lld/ELF/InputSection.cpp b/lld/ELF/InputSection.cpp
index 4717914d914..871832a4ef7 100644
--- a/lld/ELF/InputSection.cpp
+++ b/lld/ELF/InputSection.cpp
@@ -584,7 +584,18 @@ static uint64_t getRelocTargetVA(RelType Type, int64_t A, uint64_t P,
if (InOpd)
SymVA = read64be(&Out::OpdBuf[SymVA - OpdStart]);
}
- return SymVA - P;
+
+ // PPC64 V2 ABI describes two entry points to a function. The global entry
+ // point sets up the TOC base pointer. When calling a local function, the
+ // call should branch to the local entry point rather than the global entry
+ // point. Section 3.4.1 describes using the 3 most significant bits of the
+ // st_other field to find out how many instructions there are between the
+ // local and global entry point.
+ uint8_t StOther = (Sym.StOther >> 5) & 7;
+ if (StOther == 0 || StOther == 1)
+ return SymVA - P;
+
+ return SymVA - P + (1 << StOther);
}
case R_PPC_TOC:
return getPPC64TocBase() + A;