summaryrefslogtreecommitdiff
path: root/lib/ExecutionEngine/RuntimeDyld
diff options
context:
space:
mode:
authorUlrich Weigand <ulrich.weigand@de.ibm.com>2014-06-20 18:17:56 +0000
committerUlrich Weigand <ulrich.weigand@de.ibm.com>2014-06-20 18:17:56 +0000
commite29fc75ea56f08887fb8f05c9b991ff1a0f6c6dc (patch)
tree72625522f3d539c496e28d82e7548eb3c89bdc96 /lib/ExecutionEngine/RuntimeDyld
parent602941c737718bf875934f5121615eaf2596f196 (diff)
downloadllvm-e29fc75ea56f08887fb8f05c9b991ff1a0f6c6dc.tar.gz
llvm-e29fc75ea56f08887fb8f05c9b991ff1a0f6c6dc.tar.bz2
llvm-e29fc75ea56f08887fb8f05c9b991ff1a0f6c6dc.tar.xz
[RuntimeDyld] Fix ppc64 stub relocations on little-endian
When RuntimeDyldELF creates stub functions, it needs to install relocations that will resolve to the final address of the target routine. Since those are 16-bit relocs, they need to be applied to the least-significant halfword of the instruction. On big-endian ppc64, this means that addresses have to be adjusted by 2, which is what the code currently does. However, on a little-endian system, the address must *not* be adjusted; the least-significant halfword is the first one. This patch updates the RuntimeDyldELF code to take the target byte order into account. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@211384 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/ExecutionEngine/RuntimeDyld')
-rw-r--r--lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp16
1 files changed, 11 insertions, 5 deletions
diff --git a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp
index f6348be746..03e0a36ab9 100644
--- a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp
+++ b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp
@@ -1205,14 +1205,20 @@ relocation_iterator RuntimeDyldELF::processRelocationRef(
ELF::R_PPC64_ADDR64, Value.Addend);
// Generates the 64-bits address loads as exemplified in section
- // 4.5.1 in PPC64 ELF ABI.
- RelocationEntry REhst(SectionID, StubTargetAddr - Section.Address + 2,
+ // 4.5.1 in PPC64 ELF ABI. Note that the relocations need to
+ // apply to the low part of the instructions, so we have to update
+ // the offset according to the target endianness.
+ uint64_t StubRelocOffset = StubTargetAddr - Section.Address;
+ if (!IsTargetLittleEndian)
+ StubRelocOffset += 2;
+
+ RelocationEntry REhst(SectionID, StubRelocOffset + 0,
ELF::R_PPC64_ADDR16_HIGHEST, Value.Addend);
- RelocationEntry REhr(SectionID, StubTargetAddr - Section.Address + 6,
+ RelocationEntry REhr(SectionID, StubRelocOffset + 4,
ELF::R_PPC64_ADDR16_HIGHER, Value.Addend);
- RelocationEntry REh(SectionID, StubTargetAddr - Section.Address + 14,
+ RelocationEntry REh(SectionID, StubRelocOffset + 12,
ELF::R_PPC64_ADDR16_HI, Value.Addend);
- RelocationEntry REl(SectionID, StubTargetAddr - Section.Address + 18,
+ RelocationEntry REl(SectionID, StubRelocOffset + 16,
ELF::R_PPC64_ADDR16_LO, Value.Addend);
if (Value.SymbolName) {