diff options
author | Lang Hames <lhames@gmail.com> | 2014-08-27 17:41:06 +0000 |
---|---|---|
committer | Lang Hames <lhames@gmail.com> | 2014-08-27 17:41:06 +0000 |
commit | dc77feb57d832d22e4f6a97015b105caa7431df5 (patch) | |
tree | 3a753864bb33a1a58d8b85dc67e51ceabe9c7954 /llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.cpp | |
parent | 4429f149062cf067cd581fcd60f183750b19ea6d (diff) | |
download | bcm5719-llvm-dc77feb57d832d22e4f6a97015b105caa7431df5.tar.gz bcm5719-llvm-dc77feb57d832d22e4f6a97015b105caa7431df5.zip |
[MCJIT] More endianness fixes for RuntimeDyldMachO.
http://llvm.org/PR20640
llvm-svn: 216567
Diffstat (limited to 'llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.cpp')
-rw-r--r-- | llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.cpp | 27 |
1 files changed, 20 insertions, 7 deletions
diff --git a/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.cpp b/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.cpp index 35736a4df2c..9e4d3ac82af 100644 --- a/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.cpp +++ b/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.cpp @@ -29,10 +29,21 @@ namespace llvm { int64_t RuntimeDyldMachO::memcpyAddend(const RelocationEntry &RE) const { const SectionEntry &Section = Sections[RE.SectionID]; - uint8_t *LocalAddress = Section.Address + RE.Offset; unsigned NumBytes = 1 << RE.Size; int64_t Addend = 0; - memcpy(&Addend, LocalAddress, NumBytes); + uint8_t *LocalAddress = Section.Address + RE.Offset; + uint8_t *Dst = reinterpret_cast<uint8_t*>(&Addend); + + if (IsTargetLittleEndian == sys::IsLittleEndianHost) { + if (!sys::IsLittleEndianHost) + Dst += sizeof(Addend) - NumBytes; + memcpy(Dst, LocalAddress, NumBytes); + } else { + Dst += NumBytes - 1; + for (unsigned i = 0; i < NumBytes; ++i) + *Dst-- = *LocalAddress++; + } + return Addend; } @@ -113,13 +124,15 @@ void RuntimeDyldMachO::dumpRelocationToResolve(const RelocationEntry &RE, bool RuntimeDyldMachO::writeBytesUnaligned(uint8_t *Dst, uint64_t Value, unsigned Size) { - + uint8_t *Src = reinterpret_cast<uint8_t*>(&Value); // If host and target endianness match use memcpy, otherwise copy in reverse // order. - if (IsTargetLittleEndian == sys::IsLittleEndianHost) - memcpy(Dst, &Value, Size); - else { - uint8_t *Src = reinterpret_cast<uint8_t*>(&Value) + Size - 1; + if (IsTargetLittleEndian == sys::IsLittleEndianHost) { + if (!sys::IsLittleEndianHost) + Src += sizeof(Value) - Size; + memcpy(Dst, Src, Size); + } else { + Src += Size - 1; for (unsigned i = 0; i < Size; ++i) *Dst++ = *Src--; } |