summaryrefslogtreecommitdiff
path: root/lld/ELF/InputSection.cpp
diff options
context:
space:
mode:
authorSean Fertile <sfertile@ca.ibm.com>2018-09-20 00:26:47 +0000
committerSean Fertile <sfertile@ca.ibm.com>2018-09-20 00:26:47 +0000
commitfd5c6ebf0fc4fe1831e96f2d1dd5198de55973b3 (patch)
treed06abefc50d51a02e82e8e9689aa0f9e0b34eea2 /lld/ELF/InputSection.cpp
parenta29cafa3d11210dd01ae65bb132adadabb259d31 (diff)
[PPC64] Helper for offset from a function's global entry to local entry. [NFC]
The PPC64 elf V2 abi defines 2 entry points for a function. There are a few places we need to calculate the offset from the global entry to the local entry and how this is done is not straight forward. This patch adds a helper function mostly for documentation purposes, explaining how the 2 entry points differ and why we choose one over the other, as well as documenting how the offsets are encoded into a functions st_other field. Differential Revision: https://reviews.llvm.org/D52231
Diffstat (limited to 'lld/ELF/InputSection.cpp')
-rw-r--r--lld/ELF/InputSection.cpp16
1 files changed, 6 insertions, 10 deletions
diff --git a/lld/ELF/InputSection.cpp b/lld/ELF/InputSection.cpp
index a6b45e2217f..dbc12fef6d4 100644
--- a/lld/ELF/InputSection.cpp
+++ b/lld/ELF/InputSection.cpp
@@ -631,16 +631,12 @@ static uint64_t getRelocTargetVA(const InputFile *File, RelType Type, int64_t A,
return 0;
// 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 + (1LL << StOther);
+ // point is used for calls where the caller and callee (may) have different
+ // TOC base pointers and r2 needs to be modified to hold the TOC base for
+ // the callee. For local calls the caller and callee share the same
+ // TOC base and so the TOC pointer initialization code should be skipped by
+ // branching to the local entry point.
+ return SymVA - P + getPPC64GlobalEntryToLocalEntryOffset(Sym.StOther);
}
case R_PPC_TOC:
return getPPC64TocBase() + A;