[MCJIT] Move endian-aware read/writes from RuntimeDyldMachO into
authorLang Hames <lhames@gmail.com>
Fri, 29 Aug 2014 23:17:47 +0000 (23:17 +0000)
committerLang Hames <lhames@gmail.com>
Fri, 29 Aug 2014 23:17:47 +0000 (23:17 +0000)
RuntimeDyldImpl.

These are platform independent, and moving them to the base class allows
RuntimeDyldChecker to use them too.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@216801 91177308-0d34-0410-b5e6-96231b3b80d8

lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp
lib/ExecutionEngine/RuntimeDyld/RuntimeDyldChecker.cpp
lib/ExecutionEngine/RuntimeDyld/RuntimeDyldImpl.h
lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.cpp
lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.h
lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldMachOARM.h
lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldMachOI386.h
lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldMachOX86_64.h

index 7693fd5..537a683 100644 (file)
@@ -395,6 +395,38 @@ unsigned RuntimeDyldImpl::computeSectionStubBufSize(ObjectImage &Obj,
   return StubBufSize;
 }
 
+uint64_t RuntimeDyldImpl::readBytesUnaligned(uint8_t *Src,
+                                             unsigned Size) const {
+  uint64_t Result = 0;
+  uint8_t *Dst = reinterpret_cast<uint8_t*>(&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++;
+  }
+
+  return Result;
+}
+
+void RuntimeDyldImpl::writeBytesUnaligned(uint64_t Value, uint8_t *Dst,
+                                          unsigned Size) const {
+  uint8_t *Src = reinterpret_cast<uint8_t*>(&Value);
+  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--;
+  }
+}
+
 void RuntimeDyldImpl::emitCommonSymbols(ObjectImage &Obj,
                                         const CommonSymbolMap &CommonSymbols,
                                         uint64_t TotalSize,
index 72aae96..aa44802 100644 (file)
@@ -703,22 +703,8 @@ uint64_t RuntimeDyldCheckerImpl::readMemoryAtAddr(uint64_t SrcAddr,
                                                   unsigned Size) const {
   uintptr_t PtrSizedAddr = static_cast<uintptr_t>(SrcAddr);
   assert(PtrSizedAddr == SrcAddr && "Linker memory pointer out-of-range.");
-  uint64_t Result = 0;
   uint8_t *Src = reinterpret_cast<uint8_t*>(PtrSizedAddr);
-  uint8_t *Dst = reinterpret_cast<uint8_t*>(&Result);
-
-  // If host and target endianness match use memcpy, otherwise copy in reverse
-  // order.
-  if (getRTDyld().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++;
-  }
-  return Result;
+  return getRTDyld().readBytesUnaligned(Src, Size);
 }
 
 std::pair<uint64_t, std::string> RuntimeDyldCheckerImpl::getStubAddrFor(
index 379cb4a..d2c58eb 100644 (file)
@@ -286,6 +286,13 @@ protected:
     *(Addr + 7) = Value & 0xFF;
   }
 
+  /// Endian-aware read Read the least significant Size bytes from Src.
+  uint64_t readBytesUnaligned(uint8_t *Src, unsigned Size) const;
+
+  /// Endian-aware write. Write the least significant Size bytes from Value to
+  /// Dst.
+  void writeBytesUnaligned(uint64_t Value, uint8_t *Dst, unsigned Size) const;
+
   /// \brief Given the common symbols discovered in the object file, emit a
   /// new section for them and update the symbol mappings in the object and
   /// symbol table.
index a22689a..c899784 100644 (file)
@@ -28,23 +28,10 @@ using namespace llvm::object;
 namespace llvm {
 
 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);
-
-  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++;
-  }
+  uint8_t *Src = Sections[RE.SectionID].Address + RE.Offset;
 
-  return Addend;
+  return static_cast<int64_t>(readBytesUnaligned(Src, NumBytes));
 }
 
 RelocationValueRef RuntimeDyldMachO::getRelocationValueRef(
@@ -121,25 +108,6 @@ void RuntimeDyldMachO::dumpRelocationToResolve(const RelocationEntry &RE,
          << " Size: " << (1 << RE.Size) << "\n";
 }
 
-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) {
-    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;
-}
-
 bool
 RuntimeDyldMachO::isCompatibleFormat(const ObjectBuffer *InputBuffer) const {
   if (InputBuffer->getBufferSize() < 4)
index 45954a4..c017c22 100644 (file)
@@ -117,10 +117,6 @@ public:
   static std::unique_ptr<RuntimeDyldMachO> create(Triple::ArchType Arch,
                                                   RTDyldMemoryManager *mm);
 
-  /// Write the least significant 'Size' bytes in 'Value' out at the address
-  /// pointed to by Addr. Check for overflow.
-  bool writeBytesUnaligned(uint8_t *Dst, uint64_t Value, unsigned Size);
-
   SectionEntry &getSection(unsigned SectionID) { return Sections[SectionID]; }
 
   bool isCompatibleFormat(const ObjectBuffer *Buffer) const override;
index c7e650b..395ffaa 100644 (file)
@@ -98,7 +98,7 @@ public:
     default:
       llvm_unreachable("Invalid relocation type!");
     case MachO::ARM_RELOC_VANILLA:
-      writeBytesUnaligned(LocalAddress, Value, 1 << RE.Size);
+      writeBytesUnaligned(Value, LocalAddress, 1 << RE.Size);
       break;
     case MachO::ARM_RELOC_BR24: {
       // Mask the value into the target address. We know instructions are
index 07b6e63..10b1901 100644 (file)
@@ -90,7 +90,7 @@ public:
     default:
       llvm_unreachable("Invalid relocation type!");
     case MachO::GENERIC_RELOC_VANILLA:
-      writeBytesUnaligned(LocalAddress, Value + RE.Addend, 1 << RE.Size);
+      writeBytesUnaligned(Value + RE.Addend, LocalAddress, 1 << RE.Size);
       break;
     case MachO::GENERIC_RELOC_SECTDIFF:
     case MachO::GENERIC_RELOC_LOCAL_SECTDIFF: {
@@ -99,7 +99,7 @@ public:
       assert((Value == SectionABase || Value == SectionBBase) &&
              "Unexpected SECTDIFF relocation value.");
       Value = SectionABase - SectionBBase + RE.Addend;
-      writeBytesUnaligned(LocalAddress, Value, 1 << RE.Size);
+      writeBytesUnaligned(Value, LocalAddress, 1 << RE.Size);
       break;
     }
     case MachO::GENERIC_RELOC_PB_LA_PTR:
index d4f3ccd..425695c 100644 (file)
@@ -84,7 +84,7 @@ public:
     case MachO::X86_64_RELOC_SIGNED:
     case MachO::X86_64_RELOC_UNSIGNED:
     case MachO::X86_64_RELOC_BRANCH:
-      writeBytesUnaligned(LocalAddress, Value + RE.Addend, 1 << RE.Size);
+      writeBytesUnaligned(Value + RE.Addend, LocalAddress, 1 << RE.Size);
       break;
     case MachO::X86_64_RELOC_GOT_LOAD:
     case MachO::X86_64_RELOC_GOT: