From 277bb8dd4dc1d9bdd6be737e658ac268b9949c21 Mon Sep 17 00:00:00 2001 From: Lang Hames Date: Sun, 7 Sep 2014 02:05:26 +0000 Subject: [PATCH] [MCJIT] Fix a bug RuntimeDyldImpl's read/writeBytesUnaligned methods. The previous implementation was writing to the high-bytes of integers on BE targets (when run on LE hosts). http://llvm.org/PR20640 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@217325 91177308-0d34-0410-b5e6-96231b3b80d8 --- .../RuntimeDyld/RuntimeDyld.cpp | 36 +++++++++---------- 1 file changed, 17 insertions(+), 19 deletions(-) diff --git a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp index 06359b7f02b..fd276e606da 100644 --- a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp +++ b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp @@ -398,32 +398,30 @@ unsigned RuntimeDyldImpl::computeSectionStubBufSize(ObjectImage &Obj, uint64_t RuntimeDyldImpl::readBytesUnaligned(uint8_t *Src, unsigned Size) const { uint64_t Result = 0; - uint8_t *Dst = reinterpret_cast(&Result); - - if (IsTargetLittleEndian == sys::IsLittleEndianHost) { - if (!sys::IsLittleEndianHost) - Dst += sizeof(Result) - Size; - memcpy(Dst, Src, Size); - } else { - Dst += Size - 1; - for (unsigned i = 0; i < Size; ++i) - *Dst-- = *Src++; - } + if (IsTargetLittleEndian) { + Src += Size - 1; + while (Size--) + Result = (Result << 8) | *Src--; + } else + while (Size--) + Result = (Result << 8) | *Src++; return Result; } void RuntimeDyldImpl::writeBytesUnaligned(uint64_t Value, uint8_t *Dst, unsigned Size) const { - uint8_t *Src = reinterpret_cast(&Value); - if (IsTargetLittleEndian == sys::IsLittleEndianHost) { - if (!sys::IsLittleEndianHost) - Src += sizeof(Value) - Size; - memcpy(Dst, Src, Size); + if (IsTargetLittleEndian) { + while (Size--) { + *Dst++ = Value & 0xFF; + Value >>= 8; + } } else { - Src += Size - 1; - for (unsigned i = 0; i < Size; ++i) - *Dst++ = *Src--; + Dst += Size - 1; + while (Size--) { + *Dst-- = Value & 0xFF; + Value >>= 8; + } } }