Skip to content

Commit

Permalink
Fix cross-endianness RuntimeDyld relocation for ARM
Browse files Browse the repository at this point in the history
rL284780 fixed the PREL31 relocation and added a test for it. Being
the first such test for ARM relocations, it exposed incorrect endianness
assumptions (causing buildbot failures on big-endian hosts). Fix that by
using the same helpers used for the x86 case.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@284789 91177308-0d34-0410-b5e6-96231b3b80d8
  • Loading branch information
Keno committed Oct 20, 2016
1 parent 3c09f0b commit a45d706
Showing 1 changed file with 10 additions and 9 deletions.
19 changes: 10 additions & 9 deletions lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -465,12 +465,13 @@ void RuntimeDyldELF::resolveARMRelocation(const SectionEntry &Section,
break;
// Write a 31bit signed offset
case ELF::R_ARM_PREL31:
*TargetPtr &= 0x80000000;
*TargetPtr |= (Value - FinalAddress) & ~0x80000000;
support::ulittle32_t::ref{TargetPtr} =
(support::ulittle32_t::ref{TargetPtr} & 0x80000000) |
((Value - FinalAddress) & ~0x80000000);
break;
case ELF::R_ARM_TARGET1:
case ELF::R_ARM_ABS32:
*TargetPtr = Value;
support::ulittle32_t::ref{TargetPtr} = Value;
break;
// Write first 16 bit of 32 bit value to the mov instruction.
// Last 4 bit should be shifted.
Expand All @@ -480,19 +481,19 @@ void RuntimeDyldELF::resolveARMRelocation(const SectionEntry &Section,
Value = Value & 0xFFFF;
else if (Type == ELF::R_ARM_MOVT_ABS)
Value = (Value >> 16) & 0xFFFF;
*TargetPtr &= ~0x000F0FFF;
*TargetPtr |= Value & 0xFFF;
*TargetPtr |= ((Value >> 12) & 0xF) << 16;
support::ulittle32_t::ref{TargetPtr} =
(support::ulittle32_t::ref{TargetPtr} & ~0x000F0FFF) | (Value & 0xFFF) |
(((Value >> 12) & 0xF) << 16);
break;
// Write 24 bit relative value to the branch instruction.
case ELF::R_ARM_PC24: // Fall through.
case ELF::R_ARM_CALL: // Fall through.
case ELF::R_ARM_JUMP24:
int32_t RelValue = static_cast<int32_t>(Value - FinalAddress - 8);
RelValue = (RelValue & 0x03FFFFFC) >> 2;
assert((*TargetPtr & 0xFFFFFF) == 0xFFFFFE);
*TargetPtr &= 0xFF000000;
*TargetPtr |= RelValue;
assert((support::ulittle32_t::ref{TargetPtr} & 0xFFFFFF) == 0xFFFFFE);
support::ulittle32_t::ref{TargetPtr} =
(support::ulittle32_t::ref{TargetPtr} & 0xFF000000) | RelValue;
break;
}
}
Expand Down

0 comments on commit a45d706

Please sign in to comment.