[MCJIT] More endianness fixes for RuntimeDyldMachO.
[oota-llvm.git] / lib / ExecutionEngine / RuntimeDyld / RuntimeDyldMachO.cpp
index d062b10db15e50e49e00a054d981afdb211175f2..9e4d3ac82afb3d21cd86cf60a244d572fc580b34 100644 (file)
@@ -27,28 +27,24 @@ using namespace llvm::object;
 
 namespace llvm {
 
-RelocationEntry
-RuntimeDyldMachO::getBasicRelocationEntry(unsigned SectionID,
-                                          ObjectImage &ObjImg,
-                                          const relocation_iterator &RI) const {
+int64_t RuntimeDyldMachO::memcpyAddend(const RelocationEntry &RE) const {
+  const SectionEntry &Section = Sections[RE.SectionID];
+  unsigned NumBytes = 1 << RE.Size;
+  int64_t Addend = 0;
+  uint8_t *LocalAddress = Section.Address + RE.Offset;
+  uint8_t *Dst = reinterpret_cast<uint8_t*>(&Addend);
 
-  const MachOObjectFile &Obj =
-      static_cast<const MachOObjectFile &>(*ObjImg.getObjectFile());
-  MachO::any_relocation_info RelInfo =
-      Obj.getRelocation(RI->getRawDataRefImpl());
+  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++;
+  }
 
-  const SectionEntry &Section = Sections[SectionID];
-  bool IsPCRel = Obj.getAnyRelocationPCRel(RelInfo);
-  unsigned Size = Obj.getAnyRelocationLength(RelInfo);
-  uint64_t Offset;
-  RI->getOffset(Offset);
-  uint8_t *LocalAddress = Section.Address + Offset;
-  unsigned NumBytes = 1 << Size;
-  uint64_t Addend = 0;
-  memcpy(&Addend, LocalAddress, NumBytes);
-  uint32_t RelType = Obj.getAnyRelocationType(RelInfo);
-
-  return RelocationEntry(SectionID, Offset, RelType, Addend, IsPCRel, Size);
+  return Addend;
 }
 
 RelocationValueRef RuntimeDyldMachO::getRelocationValueRef(
@@ -96,7 +92,8 @@ RelocationValueRef RuntimeDyldMachO::getRelocationValueRef(
 
 void RuntimeDyldMachO::makeValueAddendPCRel(RelocationValueRef &Value,
                                             ObjectImage &ObjImg,
-                                            const relocation_iterator &RI) {
+                                            const relocation_iterator &RI,
+                                            unsigned OffsetToNextPC) {
   const MachOObjectFile &Obj =
       static_cast<const MachOObjectFile &>(*ObjImg.getObjectFile());
   MachO::any_relocation_info RelInfo =
@@ -106,8 +103,7 @@ void RuntimeDyldMachO::makeValueAddendPCRel(RelocationValueRef &Value,
   if (IsPCRel) {
     uint64_t RelocAddr = 0;
     RI->getAddress(RelocAddr);
-    unsigned RelocSize = Obj.getAnyRelocationLength(RelInfo);
-    Value.Addend += RelocAddr + (1 << RelocSize);
+    Value.Addend += RelocAddr + OffsetToNextPC;
   }
 }
 
@@ -119,17 +115,26 @@ void RuntimeDyldMachO::dumpRelocationToResolve(const RelocationEntry &RE,
 
   dbgs() << "resolveRelocation Section: " << RE.SectionID
          << " LocalAddress: " << format("%p", LocalAddress)
-         << " FinalAddress: " << format("%p", FinalAddress)
-         << " Value: " << format("%p", Value) << " Addend: " << RE.Addend
+         << " FinalAddress: " << format("0x%x", FinalAddress)
+         << " Value: " << format("0x%x", Value) << " Addend: " << RE.Addend
          << " isPCRel: " << RE.IsPCRel << " MachoType: " << RE.RelType
          << " Size: " << (1 << RE.Size) << "\n";
 }
 
-bool RuntimeDyldMachO::writeBytesUnaligned(uint8_t *Addr, uint64_t Value,
+bool RuntimeDyldMachO::writeBytesUnaligned(uint8_t *Dst, uint64_t Value,
                                            unsigned Size) {
-  for (unsigned i = 0; i < Size; ++i) {
-    *Addr++ = (uint8_t)Value;
-    Value >>= 8;
+
+  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) {
+    if (!sys::IsLittleEndianHost)
+      Src += sizeof(Value) - Size;
+    memcpy(Dst, Src, Size);
+  } else {
+    Src += Size - 1;
+    for (unsigned i = 0; i < Size; ++i)
+      *Dst++ = *Src--;
   }
 
   return false;
@@ -231,7 +236,7 @@ llvm::RuntimeDyldMachO::create(Triple::ArchType Arch, RTDyldMemoryManager *MM) {
     llvm_unreachable("Unsupported target for RuntimeDyldMachO.");
     break;
   case Triple::arm: return make_unique<RuntimeDyldMachOARM>(MM);
-  case Triple::arm64: return make_unique<RuntimeDyldMachOAArch64>(MM);
+  case Triple::aarch64: return make_unique<RuntimeDyldMachOAArch64>(MM);
   case Triple::x86: return make_unique<RuntimeDyldMachOI386>(MM);
   case Triple::x86_64: return make_unique<RuntimeDyldMachOX86_64>(MM);
   }