diff options
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--; } |