summaryrefslogtreecommitdiffstats
path: root/llvm/lib/ExecutionEngine
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
commit32626014a62e8e7015d48d840122dd148e1ed609 (patch)
tree317f48cbe18b177b01535043d0643216625f223a /llvm/lib/ExecutionEngine
parent4eff6cdd2e25a0eab795ca74a4db896f225fa7f5 (diff)
downloadbcm5719-llvm-32626014a62e8e7015d48d840122dd148e1ed609.tar.gz
bcm5719-llvm-32626014a62e8e7015d48d840122dd148e1ed609.zip
[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. llvm-svn: 211384
Diffstat (limited to 'llvm/lib/ExecutionEngine')
-rw-r--r--llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp16
1 files changed, 11 insertions, 5 deletions
diff --git a/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp b/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp
index f6348be746d..03e0a36ab90 100644
--- a/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp
+++ b/llvm/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) {
OpenPOWER on IntegriCloud