[MCJIT] More endianness fixes for RuntimeDyldMachO.
[oota-llvm.git] / lib / ExecutionEngine / RuntimeDyld / RuntimeDyldMachO.cpp
index 35736a4df2c9d92c99401cfb56b7c951898dae03..9e4d3ac82afb3d21cd86cf60a244d572fc580b34 100644 (file)
@@ -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--;
   }